From 758f62a5531b3a28c10d8e410645a022868976cd Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Fri, 4 Jun 2021 12:34:50 -0700 Subject: [PATCH 01/15] Fix Editor crash in Mac --- Registry/Platform/Mac/streamer.editor.setreg | 28 ++++++++++++++++++++ Registry/Platform/Mac/streamer.test.setreg | 24 +++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 Registry/Platform/Mac/streamer.editor.setreg create mode 100644 Registry/Platform/Mac/streamer.test.setreg diff --git a/Registry/Platform/Mac/streamer.editor.setreg b/Registry/Platform/Mac/streamer.editor.setreg new file mode 100644 index 0000000000..85360d128e --- /dev/null +++ b/Registry/Platform/Mac/streamer.editor.setreg @@ -0,0 +1,28 @@ +{ + "Amazon": + { + "AzCore": + { + "Streamer": + { + "Profiles": + { + "Generic": + { + "Stack": + [ + { + "$type": "AZ::IO::StorageDriveConfig", + // The maximum number of file handles that the drive will cache. + // On Mac the default limit for the number of file handles an application + // can have open is set to 256. So we need to set this to a lower value than on PC. + // This limit is set by "launchctl limit maxfiles" + "MaxFileHandles": 65 + } + ] + } + } + } + } + } +} \ No newline at end of file diff --git a/Registry/Platform/Mac/streamer.test.setreg b/Registry/Platform/Mac/streamer.test.setreg new file mode 100644 index 0000000000..df41b7a350 --- /dev/null +++ b/Registry/Platform/Mac/streamer.test.setreg @@ -0,0 +1,24 @@ +{ + "Amazon": + { + "AzCore": + { + "Streamer": + { + "Profiles": + { + "Generic": + { + "Stack": + [ + { + "$type": "AZ::IO::StorageDriveConfig", + "MaxFileHandles": 65 + } + ] + } + } + } + } + } +} \ No newline at end of file From 16eb3bd82c9fa842b6f654115607e50bf7a5a65e Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Fri, 4 Jun 2021 15:25:49 -0500 Subject: [PATCH 02/15] Adding newline to streamer.editor.setreg --- Registry/Platform/Mac/streamer.editor.setreg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Registry/Platform/Mac/streamer.editor.setreg b/Registry/Platform/Mac/streamer.editor.setreg index 85360d128e..2fc8197c5f 100644 --- a/Registry/Platform/Mac/streamer.editor.setreg +++ b/Registry/Platform/Mac/streamer.editor.setreg @@ -25,4 +25,4 @@ } } } -} \ No newline at end of file +} From f7caa988081eca13d0680eb89eed5af5a795224f Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Fri, 4 Jun 2021 15:26:16 -0500 Subject: [PATCH 04/15] Adding newline to streamer.test.setreg --- Registry/Platform/Mac/streamer.test.setreg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Registry/Platform/Mac/streamer.test.setreg b/Registry/Platform/Mac/streamer.test.setreg index df41b7a350..2b053a497e 100644 --- a/Registry/Platform/Mac/streamer.test.setreg +++ b/Registry/Platform/Mac/streamer.test.setreg @@ -21,4 +21,4 @@ } } } -} \ No newline at end of file +} From 6ee58b7b641ea9b7bd8727217920e0f9477bc664 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Fri, 4 Jun 2021 16:09:37 -0700 Subject: [PATCH 05/15] Fix overrides for array in editor setreg. Remove the test overrides. --- Registry/Platform/Mac/streamer.editor.setreg | 5 ++++ Registry/Platform/Mac/streamer.test.setreg | 24 -------------------- 2 files changed, 5 insertions(+), 24 deletions(-) delete mode 100644 Registry/Platform/Mac/streamer.test.setreg diff --git a/Registry/Platform/Mac/streamer.editor.setreg b/Registry/Platform/Mac/streamer.editor.setreg index 85360d128e..dafcfdc9d9 100644 --- a/Registry/Platform/Mac/streamer.editor.setreg +++ b/Registry/Platform/Mac/streamer.editor.setreg @@ -18,6 +18,11 @@ // can have open is set to 256. So we need to set this to a lower value than on PC. // This limit is set by "launchctl limit maxfiles" "MaxFileHandles": 65 + }, + { + "$type": "AzFramework::RemoteStorageDriveConfig", + // The maximum number of file handles that the drive will cache. + "MaxFileHandles": 1024 } ] } diff --git a/Registry/Platform/Mac/streamer.test.setreg b/Registry/Platform/Mac/streamer.test.setreg deleted file mode 100644 index df41b7a350..0000000000 --- a/Registry/Platform/Mac/streamer.test.setreg +++ /dev/null @@ -1,24 +0,0 @@ -{ - "Amazon": - { - "AzCore": - { - "Streamer": - { - "Profiles": - { - "Generic": - { - "Stack": - [ - { - "$type": "AZ::IO::StorageDriveConfig", - "MaxFileHandles": 65 - } - ] - } - } - } - } - } -} \ No newline at end of file From 74e5090f26f957adf75f141d70cc7d3da9c0bfdd Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Fri, 4 Jun 2021 18:08:52 -0700 Subject: [PATCH 06/15] Adding ExternalWarningLevel to the Directory.Build.props to get the default warning level for external headers to match the one we define through compile options (#1160) --- cmake/Platform/Common/Directory.Build.props | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmake/Platform/Common/Directory.Build.props b/cmake/Platform/Common/Directory.Build.props index b74fa48471..951d3c6605 100644 --- a/cmake/Platform/Common/Directory.Build.props +++ b/cmake/Platform/Common/Directory.Build.props @@ -15,4 +15,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. true true + + + TurnOffAllWarnings + + \ No newline at end of file From 3b60bcc0f1ab6707017d5698f55aa471e9ff598b Mon Sep 17 00:00:00 2001 From: AMZN-nggieber <52797929+AMZN-nggieber@users.noreply.github.com> Date: Fri, 4 Jun 2021 18:41:30 -0700 Subject: [PATCH 07/15] Project Manager Build Project from Projects Page (#1142) * Added loading bar mode to project button * Added ProjectBuilder files * commmit current progress for project building * Push current project building work * Full build commands built out and message boxes for lots of situation * Replaced defaultProjectImage placeholder * Added installed cmake path to builder process env PATH --- .../Resources/DefaultProjectImage.png | 4 +- .../Resources/ProjectManager.qss | 13 + .../Source/CreateProjectCtrl.cpp | 2 + .../ProjectManager/Source/ProjectBuilder.cpp | 250 ++++++++++++ .../ProjectManager/Source/ProjectBuilder.h | 73 ++++ .../Source/ProjectButtonWidget.cpp | 109 +++++- .../Source/ProjectButtonWidget.h | 19 +- .../ProjectManager/Source/ProjectInfo.cpp | 4 +- .../Tools/ProjectManager/Source/ProjectInfo.h | 4 +- .../ProjectManager/Source/ProjectUtils.cpp | 48 ++- .../ProjectManager/Source/ProjectUtils.h | 3 + .../ProjectManager/Source/ProjectsScreen.cpp | 361 ++++++++++++++---- .../ProjectManager/Source/ProjectsScreen.h | 35 +- .../ProjectManager/Source/PythonBindings.cpp | 2 +- .../ProjectManager/Source/ScreenWidget.h | 2 + .../ProjectManager/Source/ScreensCtrl.cpp | 1 + .../Tools/ProjectManager/Source/ScreensCtrl.h | 2 + .../Source/UpdateProjectCtrl.cpp | 14 +- .../project_manager_files.cmake | 2 + 19 files changed, 834 insertions(+), 114 deletions(-) create mode 100644 Code/Tools/ProjectManager/Source/ProjectBuilder.cpp create mode 100644 Code/Tools/ProjectManager/Source/ProjectBuilder.h diff --git a/Code/Tools/ProjectManager/Resources/DefaultProjectImage.png b/Code/Tools/ProjectManager/Resources/DefaultProjectImage.png index cc1eda5bb8..a3e13481c9 100644 --- a/Code/Tools/ProjectManager/Resources/DefaultProjectImage.png +++ b/Code/Tools/ProjectManager/Resources/DefaultProjectImage.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f82f22df64b93d4bec91e56b60efa3d5ce2915ce388a2dc627f1ab720678e3d5 -size 334987 +oid sha256:4a5881b8d6cfbc4ceefb14ab96844484fe19407ee030824768f9fcce2f729d35 +size 2949 diff --git a/Code/Tools/ProjectManager/Resources/ProjectManager.qss b/Code/Tools/ProjectManager/Resources/ProjectManager.qss index 8b7470051c..c18d61fc24 100644 --- a/Code/Tools/ProjectManager/Resources/ProjectManager.qss +++ b/Code/Tools/ProjectManager/Resources/ProjectManager.qss @@ -362,6 +362,7 @@ QTabBar::tab:pressed #projectButton > #labelButton { border:1px solid white; } + #projectButton > #labelButton:hover, #projectButton > #labelButton:pressed { border:1px solid #1e70eb; @@ -401,6 +402,18 @@ QTabBar::tab:pressed max-height:278px; } +QProgressBar { + border: none; + background-color: transparent; + padding: 0px; + min-height: 14px; + font-size: 2px; +} + +QProgressBar::chunk { + background-color: #1E70EB; +} + /************** Gem Catalog **************/ #GemCatalogTitle { diff --git a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp index 4498a6bc82..c8ed3954ac 100644 --- a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp @@ -206,6 +206,8 @@ namespace O3DE::ProjectManager m_gemCatalogScreen->EnableDisableGemsForProject(projectInfo.m_path); #endif // TEMPLATE_GEM_CONFIGURATION_ENABLED + projectInfo.m_needsBuild = true; + emit NotifyBuildProject(projectInfo); emit ChangeScreenRequest(ProjectManagerScreen::Projects); } else diff --git a/Code/Tools/ProjectManager/Source/ProjectBuilder.cpp b/Code/Tools/ProjectManager/Source/ProjectBuilder.cpp new file mode 100644 index 0000000000..8cdab93c6a --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ProjectBuilder.cpp @@ -0,0 +1,250 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +//#define MOCK_BUILD_PROJECT true + +namespace O3DE::ProjectManager +{ + // 10 Minutes + constexpr int MaxBuildTimeMSecs = 600000; + static const QString BuildPathPostfix = "windows_vs2019"; + static const QString ErrorLogPathPostfix = "CMakeFiles/CMakeProjectBuildError.log"; + + ProjectBuilderWorker::ProjectBuilderWorker(const ProjectInfo& projectInfo) + : QObject() + , m_projectInfo(projectInfo) + { + } + + void ProjectBuilderWorker::BuildProject() + { +#ifdef MOCK_BUILD_PROJECT + for (int i = 0; i < 10; ++i) + { + QThread::sleep(1); + UpdateProgress(i * 10); + } + Done(m_projectPath); +#else + EngineInfo engineInfo; + + AZ::Outcome engineInfoResult = PythonBindingsInterface::Get()->GetEngineInfo(); + if (engineInfoResult.IsSuccess()) + { + engineInfo = engineInfoResult.GetValue(); + } + else + { + emit Done(tr("Failed to get engine info.")); + return; + } + + // Show some kind of progress with very approximate estimates + UpdateProgress(1); + + QProcessEnvironment currentEnvironment(QProcessEnvironment::systemEnvironment()); + // Append cmake path to PATH incase it is missing + QDir cmakePath(engineInfo.m_path); + cmakePath.cd("cmake/runtime/bin"); + QString pathValue = currentEnvironment.value("PATH"); + pathValue += ";" + cmakePath.path(); + currentEnvironment.insert("PATH", pathValue); + + QProcess configProjectProcess; + configProjectProcess.setProcessChannelMode(QProcess::MergedChannels); + configProjectProcess.setWorkingDirectory(m_projectInfo.m_path); + configProjectProcess.setProcessEnvironment(currentEnvironment); + + configProjectProcess.start( + "cmake", + QStringList + { + "-B", + QDir(m_projectInfo.m_path).filePath(BuildPathPostfix), + "-S", + m_projectInfo.m_path, + "-G", + "Visual Studio 16", + "-DLY_3RDPARTY_PATH=" + engineInfo.m_thirdPartyPath + }); + + if (!configProjectProcess.waitForStarted()) + { + emit Done(tr("Configuring project failed to start.")); + return; + } + if (!configProjectProcess.waitForFinished(MaxBuildTimeMSecs)) + { + WriteErrorLog(configProjectProcess.readAllStandardOutput()); + emit Done(tr("Configuring project timed out. See log for details")); + return; + } + + QString configProjectOutput(configProjectProcess.readAllStandardOutput()); + if (configProjectProcess.exitCode() != 0 || !configProjectOutput.contains("Generating done")) + { + WriteErrorLog(configProjectOutput); + emit Done(tr("Configuring project failed. See log for details.")); + return; + } + + UpdateProgress(20); + + QProcess buildProjectProcess; + buildProjectProcess.setProcessChannelMode(QProcess::MergedChannels); + buildProjectProcess.setWorkingDirectory(m_projectInfo.m_path); + buildProjectProcess.setProcessEnvironment(currentEnvironment); + + buildProjectProcess.start( + "cmake", + QStringList + { + "--build", + QDir(m_projectInfo.m_path).filePath(BuildPathPostfix), + "--target", + m_projectInfo.m_projectName + ".GameLauncher", + "Editor", + "--config", + "profile" + }); + + if (!buildProjectProcess.waitForStarted()) + { + emit Done(tr("Building project failed to start.")); + return; + } + if (!buildProjectProcess.waitForFinished(MaxBuildTimeMSecs)) + { + WriteErrorLog(configProjectProcess.readAllStandardOutput()); + emit Done(tr("Building project timed out. See log for details")); + return; + } + + QString buildProjectOutput(buildProjectProcess.readAllStandardOutput()); + if (configProjectProcess.exitCode() != 0) + { + WriteErrorLog(buildProjectOutput); + emit Done(tr("Building project failed. See log for details.")); + } + else + { + emit Done(""); + } +#endif + } + + QString ProjectBuilderWorker::LogFilePath() const + { + QDir logFilePath(m_projectInfo.m_path); + logFilePath.cd(BuildPathPostfix); + return logFilePath.filePath(ErrorLogPathPostfix); + } + + void ProjectBuilderWorker::WriteErrorLog(const QString& log) + { + QFile logFile(LogFilePath()); + // Overwrite file with truncate + if (logFile.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) + { + QTextStream output(&logFile); + output << log; + logFile.close(); + } + } + + ProjectBuilderController::ProjectBuilderController(const ProjectInfo& projectInfo, ProjectButton* projectButton, QWidget* parent) + : QObject() + , m_projectInfo(projectInfo) + , m_projectButton(projectButton) + , m_parent(parent) + { + m_worker = new ProjectBuilderWorker(m_projectInfo); + m_worker->moveToThread(&m_workerThread); + + connect(&m_workerThread, &QThread::finished, m_worker, &ProjectBuilderWorker::deleteLater); + connect(&m_workerThread, &QThread::started, m_worker, &ProjectBuilderWorker::BuildProject); + connect(m_worker, &ProjectBuilderWorker::Done, this, &ProjectBuilderController::HandleResults); + connect(m_worker, &ProjectBuilderWorker::UpdateProgress, this, &ProjectBuilderController::UpdateUIProgress); + } + + ProjectBuilderController::~ProjectBuilderController() + { + m_workerThread.quit(); + m_workerThread.wait(); + } + + void ProjectBuilderController::Start() + { + m_workerThread.start(); + UpdateUIProgress(0); + } + + void ProjectBuilderController::SetProjectButton(ProjectButton* projectButton) + { + m_projectButton = projectButton; + } + + QString ProjectBuilderController::GetProjectPath() const + { + return m_projectInfo.m_path; + } + + void ProjectBuilderController::UpdateUIProgress(int progress) + { + if (m_projectButton) + { + m_projectButton->SetButtonOverlayText(QString("%1 (%2%)\n\n").arg(tr("Building Project..."), QString::number(progress))); + m_projectButton->SetProgressBarValue(progress); + } + } + + void ProjectBuilderController::HandleResults(const QString& result) + { + if (!result.isEmpty()) + { + if (result.contains(tr("log"))) + { + QMessageBox::StandardButton openLog = QMessageBox::critical( + m_parent, + tr("Project Failed to Build!"), + result + tr("\n\nWould you like to view log?"), + QMessageBox::No | QMessageBox::Yes); + + if (openLog == QMessageBox::Yes) + { + // Open application assigned to this file type + QDesktopServices::openUrl(QUrl("file:///" + m_worker->LogFilePath())); + } + } + else + { + QMessageBox::critical(m_parent, tr("Project Failed to Build!"), result); + } + } + + emit Done(); + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectBuilder.h b/Code/Tools/ProjectManager/Source/ProjectBuilder.h new file mode 100644 index 0000000000..de84a351ee --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ProjectBuilder.h @@ -0,0 +1,73 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ +#pragma once + +#if !defined(Q_MOC_RUN) +#include + +#include +#endif + +namespace O3DE::ProjectManager +{ + QT_FORWARD_DECLARE_CLASS(ProjectButton) + + class ProjectBuilderWorker : public QObject + { + Q_OBJECT + + public: + explicit ProjectBuilderWorker(const ProjectInfo& projectInfo); + ~ProjectBuilderWorker() = default; + + QString LogFilePath() const; + + public slots: + void BuildProject(); + + signals: + void UpdateProgress(int progress); + void Done(QString result); + + private: + void WriteErrorLog(const QString& log); + + ProjectInfo m_projectInfo; + }; + + class ProjectBuilderController : public QObject + { + Q_OBJECT + + public: + explicit ProjectBuilderController(const ProjectInfo& projectInfo, ProjectButton* projectButton, QWidget* parent = nullptr); + ~ProjectBuilderController(); + + void SetProjectButton(ProjectButton* projectButton); + QString GetProjectPath() const; + + public slots: + void Start(); + void UpdateUIProgress(int progress); + void HandleResults(const QString& result); + + signals: + void Done(); + + private: + ProjectInfo m_projectInfo; + ProjectBuilderWorker* m_worker; + QThread m_workerThread; + ProjectButton* m_projectButton; + QWidget* m_parent; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp index ee4d48fe7f..db1b1a4850 100644 --- a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace O3DE::ProjectManager { @@ -31,11 +32,26 @@ namespace O3DE::ProjectManager : QLabel(parent) { setObjectName("labelButton"); + + QVBoxLayout* vLayout = new QVBoxLayout(this); + vLayout->setContentsMargins(0, 0, 0, 0); + vLayout->setSpacing(5); + + setLayout(vLayout); m_overlayLabel = new QLabel("", this); m_overlayLabel->setObjectName("labelButtonOverlay"); m_overlayLabel->setWordWrap(true); m_overlayLabel->setAlignment(Qt::AlignCenter); m_overlayLabel->setVisible(false); + vLayout->addWidget(m_overlayLabel); + + m_buildButton = new QPushButton(tr("Build Project"), this); + m_buildButton->setVisible(false); + + m_progressBar = new QProgressBar(this); + m_progressBar->setObjectName("labelButtonProgressBar"); + m_progressBar->setVisible(false); + vLayout->addWidget(m_progressBar); } void LabelButton::mousePressEvent([[maybe_unused]] QMouseEvent* event) @@ -57,7 +73,22 @@ namespace O3DE::ProjectManager m_overlayLabel->setText(text); } - ProjectButton::ProjectButton(const ProjectInfo& projectInfo, QWidget* parent) + QLabel* LabelButton::GetOverlayLabel() + { + return m_overlayLabel; + } + + QProgressBar* LabelButton::GetProgressBar() + { + return m_progressBar; + } + + QPushButton* LabelButton::GetBuildButton() + { + return m_buildButton; + } + + ProjectButton::ProjectButton(const ProjectInfo& projectInfo, QWidget* parent, bool processing) : QFrame(parent) , m_projectInfo(projectInfo) { @@ -66,10 +97,18 @@ namespace O3DE::ProjectManager m_projectInfo.m_imagePath = ":/DefaultProjectImage.png"; } - Setup(); + BaseSetup(); + if (processing) + { + ProcessingSetup(); + } + else + { + ReadySetup(); + } } - void ProjectButton::Setup() + void ProjectButton::BaseSetup() { setObjectName("projectButton"); @@ -87,8 +126,37 @@ namespace O3DE::ProjectManager m_projectImageLabel->setPixmap( QPixmap(m_projectInfo.m_imagePath).scaled(m_projectImageLabel->size(), Qt::KeepAspectRatioByExpanding)); + m_projectFooter = new QFrame(this); + QHBoxLayout* hLayout = new QHBoxLayout(); + hLayout->setContentsMargins(0, 0, 0, 0); + m_projectFooter->setLayout(hLayout); + { + QLabel* projectNameLabel = new QLabel(m_projectInfo.m_displayName, this); + hLayout->addWidget(projectNameLabel); + } + + vLayout->addWidget(m_projectFooter); + } + + void ProjectButton::ProcessingSetup() + { + m_projectImageLabel->GetOverlayLabel()->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); + m_projectImageLabel->SetEnabled(false); + m_projectImageLabel->SetOverlayText(tr("Processing...\n\n")); + + QProgressBar* progressBar = m_projectImageLabel->GetProgressBar(); + progressBar->setVisible(true); + progressBar->setValue(0); + } + + void ProjectButton::ReadySetup() + { + connect(m_projectImageLabel, &LabelButton::triggered, [this]() { emit OpenProject(m_projectInfo.m_path); }); + connect(m_projectImageLabel->GetBuildButton(), &QPushButton::clicked, [this](){ emit BuildProject(m_projectInfo); }); + QMenu* menu = new QMenu(this); menu->addAction(tr("Edit Project Settings..."), this, [this]() { emit EditProject(m_projectInfo.m_path); }); + menu->addAction(tr("Build"), this, [this]() { emit BuildProject(m_projectInfo); }); menu->addSeparator(); menu->addAction(tr("Open Project folder..."), this, [this]() { @@ -100,30 +168,33 @@ namespace O3DE::ProjectManager menu->addAction(tr("Remove from O3DE"), this, [this]() { emit RemoveProject(m_projectInfo.m_path); }); menu->addAction(tr("Delete this Project"), this, [this]() { emit DeleteProject(m_projectInfo.m_path); }); - QFrame* footer = new QFrame(this); - QHBoxLayout* hLayout = new QHBoxLayout(); - hLayout->setContentsMargins(0, 0, 0, 0); - footer->setLayout(hLayout); - { - QLabel* projectNameLabel = new QLabel(m_projectInfo.m_displayName, this); - hLayout->addWidget(projectNameLabel); - - QPushButton* projectMenuButton = new QPushButton(this); - projectMenuButton->setObjectName("projectMenuButton"); - projectMenuButton->setMenu(menu); - hLayout->addWidget(projectMenuButton); - } - - vLayout->addWidget(footer); + QPushButton* projectMenuButton = new QPushButton(this); + projectMenuButton->setObjectName("projectMenuButton"); + projectMenuButton->setMenu(menu); + m_projectFooter->layout()->addWidget(projectMenuButton); } - void ProjectButton::SetButtonEnabled(bool enabled) + void ProjectButton::SetLaunchButtonEnabled(bool enabled) { m_projectImageLabel->SetEnabled(enabled); } + void ProjectButton::ShowBuildButton(bool show) + { + QSpacerItem* buttonSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding); + + m_projectImageLabel->layout()->addItem(buttonSpacer); + m_projectImageLabel->layout()->addWidget(m_projectImageLabel->GetBuildButton()); + m_projectImageLabel->GetBuildButton()->setVisible(show); + } + void ProjectButton::SetButtonOverlayText(const QString& text) { m_projectImageLabel->SetOverlayText(text); } + + void ProjectButton::SetProgressBarValue(int progress) + { + m_projectImageLabel->GetProgressBar()->setValue(progress); + } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h index bb61f7354b..1178c8ea76 100644 --- a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h +++ b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h @@ -21,6 +21,7 @@ QT_FORWARD_DECLARE_CLASS(QPixmap) QT_FORWARD_DECLARE_CLASS(QPushButton) QT_FORWARD_DECLARE_CLASS(QAction) +QT_FORWARD_DECLARE_CLASS(QProgressBar) namespace O3DE::ProjectManager { @@ -36,6 +37,10 @@ namespace O3DE::ProjectManager void SetEnabled(bool enabled); void SetOverlayText(const QString& text); + QLabel* GetOverlayLabel(); + QProgressBar* GetProgressBar(); + QPushButton* GetBuildButton(); + signals: void triggered(); @@ -44,6 +49,8 @@ namespace O3DE::ProjectManager private: QLabel* m_overlayLabel; + QProgressBar* m_progressBar; + QPushButton* m_buildButton; bool m_enabled = true; }; @@ -53,11 +60,13 @@ namespace O3DE::ProjectManager Q_OBJECT // AUTOMOC public: - explicit ProjectButton(const ProjectInfo& m_projectInfo, QWidget* parent = nullptr); + explicit ProjectButton(const ProjectInfo& m_projectInfo, QWidget* parent = nullptr, bool processing = false); ~ProjectButton() = default; - void SetButtonEnabled(bool enabled); + void SetLaunchButtonEnabled(bool enabled); + void ShowBuildButton(bool show); void SetButtonOverlayText(const QString& text); + void SetProgressBarValue(int progress); signals: void OpenProject(const QString& projectName); @@ -65,11 +74,15 @@ namespace O3DE::ProjectManager void CopyProject(const QString& projectName); void RemoveProject(const QString& projectName); void DeleteProject(const QString& projectName); + void BuildProject(const ProjectInfo& projectInfo); private: - void Setup(); + void BaseSetup(); + void ProcessingSetup(); + void ReadySetup(); ProjectInfo m_projectInfo; LabelButton* m_projectImageLabel; + QFrame* m_projectFooter; }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectInfo.cpp b/Code/Tools/ProjectManager/Source/ProjectInfo.cpp index f0dc05cc62..da0b4ebd61 100644 --- a/Code/Tools/ProjectManager/Source/ProjectInfo.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectInfo.cpp @@ -15,13 +15,13 @@ namespace O3DE::ProjectManager { ProjectInfo::ProjectInfo(const QString& path, const QString& projectName, const QString& displayName, - const QString& imagePath, const QString& backgroundImagePath, bool isNew) + const QString& imagePath, const QString& backgroundImagePath, bool needsBuild) : m_path(path) , m_projectName(projectName) , m_displayName(displayName) , m_imagePath(imagePath) , m_backgroundImagePath(backgroundImagePath) - , m_isNew(isNew) + , m_needsBuild(needsBuild) { } diff --git a/Code/Tools/ProjectManager/Source/ProjectInfo.h b/Code/Tools/ProjectManager/Source/ProjectInfo.h index 71fa12b344..857e6ea4d5 100644 --- a/Code/Tools/ProjectManager/Source/ProjectInfo.h +++ b/Code/Tools/ProjectManager/Source/ProjectInfo.h @@ -24,7 +24,7 @@ namespace O3DE::ProjectManager public: ProjectInfo() = default; ProjectInfo(const QString& path, const QString& projectName, const QString& displayName, - const QString& imagePath, const QString& backgroundImagePath, bool isNew); + const QString& imagePath, const QString& backgroundImagePath, bool needsBuild); bool operator==(const ProjectInfo& rhs); bool operator!=(const ProjectInfo& rhs); @@ -42,6 +42,6 @@ namespace O3DE::ProjectManager QString m_backgroundImagePath; // Used in project creation - bool m_isNew = false; //! Is this a new project or existing + bool m_needsBuild = false; //! Does this project need to be built }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectUtils.cpp b/Code/Tools/ProjectManager/Source/ProjectUtils.cpp index 58e4c5c60f..3e2b3c13e1 100644 --- a/Code/Tools/ProjectManager/Source/ProjectUtils.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectUtils.cpp @@ -16,7 +16,9 @@ #include #include #include -#include +#include +#include +#include namespace O3DE::ProjectManager { @@ -192,6 +194,49 @@ namespace O3DE::ProjectManager return true; } + static bool IsVS2019Installed_internal() + { + QProcessEnvironment environment = QProcessEnvironment::systemEnvironment(); + QString programFilesPath = environment.value("ProgramFiles(x86)"); + QString vsWherePath = programFilesPath + "\\Microsoft Visual Studio\\Installer\\vswhere.exe"; + + QFileInfo vsWhereFile(vsWherePath); + if (vsWhereFile.exists() && vsWhereFile.isFile()) + { + QProcess vsWhereProcess; + vsWhereProcess.setProcessChannelMode(QProcess::MergedChannels); + + vsWhereProcess.start( + vsWherePath, + QStringList{ "-version", "16.0", "-latest", "-requires", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", + "-property", "isComplete" }); + + if (!vsWhereProcess.waitForStarted()) + { + return false; + } + + while (vsWhereProcess.waitForReadyRead()) + { + } + + QString vsWhereOutput(vsWhereProcess.readAllStandardOutput()); + if (vsWhereOutput.startsWith("1")) + { + return true; + } + } + + return false; + } + + bool IsVS2019Installed() + { + static bool vs2019Installed = IsVS2019Installed_internal(); + + return vs2019Installed; + } + ProjectManagerScreen GetProjectManagerScreen(const QString& screen) { auto iter = s_ProjectManagerStringNames.find(screen); @@ -202,6 +247,5 @@ namespace O3DE::ProjectManager return ProjectManagerScreen::Invalid; } - } // namespace ProjectUtils } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectUtils.h b/Code/Tools/ProjectManager/Source/ProjectUtils.h index d556d682f2..9c711ad187 100644 --- a/Code/Tools/ProjectManager/Source/ProjectUtils.h +++ b/Code/Tools/ProjectManager/Source/ProjectUtils.h @@ -25,6 +25,9 @@ namespace O3DE::ProjectManager bool CopyProject(const QString& origPath, const QString& newPath); bool DeleteProjectFiles(const QString& path, bool force = false); bool MoveProject(const QString& origPath, const QString& newPath, QWidget* parent = nullptr); + + bool IsVS2019Installed(); + ProjectManagerScreen GetProjectManagerScreen(const QString& screen); } // namespace ProjectUtils } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectsScreen.cpp b/Code/Tools/ProjectManager/Source/ProjectsScreen.cpp index 425aa8514d..8e41e52643 100644 --- a/Code/Tools/ProjectManager/Source/ProjectsScreen.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectsScreen.cpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -42,6 +44,8 @@ #include #include #include +#include +#include //#define DISPLAY_PROJECT_DEV_DATA true @@ -66,6 +70,14 @@ namespace O3DE::ProjectManager m_stack->addWidget(m_projectsContent); vLayout->addWidget(m_stack); + + connect(reinterpret_cast(parent), &ScreensCtrl::NotifyBuildProject, this, &ProjectsScreen::SuggestBuildProject); + } + + ProjectsScreen::~ProjectsScreen() + + { + delete m_currentBuilder; } QFrame* ProjectsScreen::CreateFirstTimeContent() @@ -110,7 +122,7 @@ namespace O3DE::ProjectManager return frame; } - QFrame* ProjectsScreen::CreateProjectsContent() + QFrame* ProjectsScreen::CreateProjectsContent(QString buildProjectPath, ProjectButton** projectButton) { QFrame* frame = new QFrame(this); frame->setObjectName("projectsContent"); @@ -158,30 +170,43 @@ namespace O3DE::ProjectManager projectsScrollArea->setWidgetResizable(true); #ifndef DISPLAY_PROJECT_DEV_DATA + // Iterate once to insert building project first + if (!buildProjectPath.isEmpty()) + { + buildProjectPath = QDir::fromNativeSeparators(buildProjectPath); + for (auto project : projectsResult.GetValue()) + { + if (QDir::fromNativeSeparators(project.m_path) == buildProjectPath) + { + ProjectButton* buildingProjectButton = CreateProjectButton(project, flowLayout, true); + + if (projectButton) + { + *projectButton = buildingProjectButton; + } + + break; + } + } + } + for (auto project : projectsResult.GetValue()) #else ProjectInfo project = projectsResult.GetValue().at(0); for (int i = 0; i < 15; i++) #endif { - ProjectButton* projectButton; - - QString projectPreviewPath = project.m_path + m_projectPreviewImagePath; - QFileInfo doesPreviewExist(projectPreviewPath); - if (doesPreviewExist.exists() && doesPreviewExist.isFile()) + // Add all other projects skipping building project + // Safe if no building project because it is just an empty string + if (project.m_path != buildProjectPath) { - project.m_imagePath = projectPreviewPath; - } - - projectButton = new ProjectButton(project, this); - - flowLayout->addWidget(projectButton); + ProjectButton* projectButtonWidget = CreateProjectButton(project, flowLayout); - connect(projectButton, &ProjectButton::OpenProject, this, &ProjectsScreen::HandleOpenProject); - connect(projectButton, &ProjectButton::EditProject, this, &ProjectsScreen::HandleEditProject); - connect(projectButton, &ProjectButton::CopyProject, this, &ProjectsScreen::HandleCopyProject); - connect(projectButton, &ProjectButton::RemoveProject, this, &ProjectsScreen::HandleRemoveProject); - connect(projectButton, &ProjectButton::DeleteProject, this, &ProjectsScreen::HandleDeleteProject); + if (RequiresBuildProjectIterator(project.m_path) != m_requiresBuild.end()) + { + projectButtonWidget->ShowBuildButton(true); + } + } } layout->addWidget(projectsScrollArea); @@ -191,6 +216,60 @@ namespace O3DE::ProjectManager return frame; } + ProjectButton* ProjectsScreen::CreateProjectButton(ProjectInfo& project, QLayout* flowLayout, bool processing) + { + ProjectButton* projectButton; + + QString projectPreviewPath = project.m_path + m_projectPreviewImagePath; + QFileInfo doesPreviewExist(projectPreviewPath); + if (doesPreviewExist.exists() && doesPreviewExist.isFile()) + { + project.m_imagePath = projectPreviewPath; + } + + projectButton = new ProjectButton(project, this, processing); + + flowLayout->addWidget(projectButton); + + if (!processing) + { + connect(projectButton, &ProjectButton::OpenProject, this, &ProjectsScreen::HandleOpenProject); + connect(projectButton, &ProjectButton::EditProject, this, &ProjectsScreen::HandleEditProject); + connect(projectButton, &ProjectButton::CopyProject, this, &ProjectsScreen::HandleCopyProject); + connect(projectButton, &ProjectButton::RemoveProject, this, &ProjectsScreen::HandleRemoveProject); + connect(projectButton, &ProjectButton::DeleteProject, this, &ProjectsScreen::HandleDeleteProject); + } + connect(projectButton, &ProjectButton::BuildProject, this, &ProjectsScreen::QueueBuildProject); + + return projectButton; + } + + void ProjectsScreen::ResetProjectsContent() + { + // refresh the projects content by re-creating it for now + if (m_projectsContent) + { + m_stack->removeWidget(m_projectsContent); + m_projectsContent->deleteLater(); + } + + // Make sure to update builder with latest Project Button + if (m_currentBuilder) + { + ProjectButton* projectButtonPtr; + + m_projectsContent = CreateProjectsContent(m_currentBuilder->GetProjectPath(), &projectButtonPtr); + m_currentBuilder->SetProjectButton(projectButtonPtr); + } + else + { + m_projectsContent = CreateProjectsContent(); + } + + m_stack->addWidget(m_projectsContent); + m_stack->setCurrentWidget(m_projectsContent); + } + ProjectManagerScreen ProjectsScreen::GetScreenEnum() { return ProjectManagerScreen::Projects; @@ -237,7 +316,7 @@ namespace O3DE::ProjectManager { if (ProjectUtils::AddProjectDialog(this)) { - emit ResetScreenRequest(ProjectManagerScreen::Projects); + ResetProjectsContent(); emit ChangeScreenRequest(ProjectManagerScreen::Projects); } } @@ -245,38 +324,47 @@ namespace O3DE::ProjectManager { if (!projectPath.isEmpty()) { - AZ::IO::FixedMaxPath executableDirectory = AZ::Utils::GetExecutableDirectory(); - AZStd::string executableFilename = "Editor"; - AZ::IO::FixedMaxPath editorExecutablePath = executableDirectory / (executableFilename + AZ_TRAIT_OS_EXECUTABLE_EXTENSION); - auto cmdPath = AZ::IO::FixedMaxPathString::format("%s -regset=\"/Amazon/AzCore/Bootstrap/project_path=%s\"", editorExecutablePath.c_str(), projectPath.toStdString().c_str()); - - AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo; - processLaunchInfo.m_commandlineParameters = cmdPath; - bool launchSucceeded = AzFramework::ProcessLauncher::LaunchUnwatchedProcess(processLaunchInfo); - if (!launchSucceeded) + if (!WarnIfInBuildQueue(projectPath)) { - AZ_Error("ProjectManager", false, "Failed to launch editor"); - QMessageBox::critical( this, tr("Error"), tr("Failed to launch the Editor, please verify the project settings are valid.")); - } - else - { - // prevent the user from accidentally pressing the button while the editor is launching - // and let them know what's happening - ProjectButton* button = qobject_cast(sender()); - if (button) + AZ::IO::FixedMaxPath executableDirectory = AZ::Utils::GetExecutableDirectory(); + AZStd::string executableFilename = "Editor"; + AZ::IO::FixedMaxPath editorExecutablePath = executableDirectory / (executableFilename + AZ_TRAIT_OS_EXECUTABLE_EXTENSION); + auto cmdPath = AZ::IO::FixedMaxPathString::format( + "%s -regset=\"/Amazon/AzCore/Bootstrap/project_path=%s\"", editorExecutablePath.c_str(), + projectPath.toStdString().c_str()); + + AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo; + processLaunchInfo.m_commandlineParameters = cmdPath; + bool launchSucceeded = AzFramework::ProcessLauncher::LaunchUnwatchedProcess(processLaunchInfo); + if (!launchSucceeded) { - button->SetButtonEnabled(false); - button->SetButtonOverlayText(tr("Opening Editor...")); + AZ_Error("ProjectManager", false, "Failed to launch editor"); + QMessageBox::critical( + this, tr("Error"), tr("Failed to launch the Editor, please verify the project settings are valid.")); } + else + { + // prevent the user from accidentally pressing the button while the editor is launching + // and let them know what's happening + ProjectButton* button = qobject_cast(sender()); + if (button) + { + button->SetLaunchButtonEnabled(false); + button->SetButtonOverlayText(tr("Opening Editor...")); + } - // enable the button after 3 seconds - constexpr int waitTimeInMs = 3000; - QTimer::singleShot(waitTimeInMs, this, [this, button] { - if (button) + // enable the button after 3 seconds + constexpr int waitTimeInMs = 3000; + QTimer::singleShot( + waitTimeInMs, this, + [this, button] { - button->SetButtonEnabled(true); - } - }); + if (button) + { + button->SetLaunchButtonEnabled(true); + } + }); + } } } else @@ -288,38 +376,90 @@ namespace O3DE::ProjectManager } void ProjectsScreen::HandleEditProject(const QString& projectPath) { - emit NotifyCurrentProject(projectPath); - emit ChangeScreenRequest(ProjectManagerScreen::UpdateProject); + if (!WarnIfInBuildQueue(projectPath)) + { + emit NotifyCurrentProject(projectPath); + emit ChangeScreenRequest(ProjectManagerScreen::UpdateProject); + } } void ProjectsScreen::HandleCopyProject(const QString& projectPath) { - // Open file dialog and choose location for copied project then register copy with O3DE - if (ProjectUtils::CopyProjectDialog(projectPath, this)) + if (!WarnIfInBuildQueue(projectPath)) { - emit ResetScreenRequest(ProjectManagerScreen::Projects); - emit ChangeScreenRequest(ProjectManagerScreen::Projects); + // Open file dialog and choose location for copied project then register copy with O3DE + if (ProjectUtils::CopyProjectDialog(projectPath, this)) + { + ResetProjectsContent(); + emit ChangeScreenRequest(ProjectManagerScreen::Projects); + } } } void ProjectsScreen::HandleRemoveProject(const QString& projectPath) { - // Unregister Project from O3DE and reload projects - if (ProjectUtils::UnregisterProject(projectPath)) + if (!WarnIfInBuildQueue(projectPath)) { - emit ResetScreenRequest(ProjectManagerScreen::Projects); - emit ChangeScreenRequest(ProjectManagerScreen::Projects); + // Unregister Project from O3DE and reload projects + if (ProjectUtils::UnregisterProject(projectPath)) + { + ResetProjectsContent(); + emit ChangeScreenRequest(ProjectManagerScreen::Projects); + } } } void ProjectsScreen::HandleDeleteProject(const QString& projectPath) { - QMessageBox::StandardButton warningResult = QMessageBox::warning( - this, tr("Delete Project"), tr("Are you sure?\nProject will be removed from O3DE and directory will be deleted!"), - QMessageBox::No | QMessageBox::Yes); + if (!WarnIfInBuildQueue(projectPath)) + { + QMessageBox::StandardButton warningResult = QMessageBox::warning(this, + tr("Delete Project"), + tr("Are you sure?\nProject will be unregistered from O3DE and project directory will be deleted from your disk."), + QMessageBox::No | QMessageBox::Yes); + + if (warningResult == QMessageBox::Yes) + { + // Remove project from O3DE and delete from disk + HandleRemoveProject(projectPath); + ProjectUtils::DeleteProjectFiles(projectPath); + } + } + } - if (warningResult == QMessageBox::Yes) + void ProjectsScreen::SuggestBuildProject(const ProjectInfo& projectInfo) + { + if (projectInfo.m_needsBuild) { - // Remove project from O3DE and delete from disk - HandleRemoveProject(projectPath); - ProjectUtils::DeleteProjectFiles(projectPath); + if (RequiresBuildProjectIterator(projectInfo.m_path) == m_requiresBuild.end()) + { + m_requiresBuild.append(projectInfo); + } + ResetProjectsContent(); + } + else + { + QMessageBox::information(this, + tr("Project Should be rebuilt."), + projectInfo.m_projectName + tr(" project likely needs to be rebuilt.")); + } + } + + void ProjectsScreen::QueueBuildProject(const ProjectInfo& projectInfo) + { + auto requiredIter = RequiresBuildProjectIterator(projectInfo.m_path); + if (requiredIter != m_requiresBuild.end()) + { + m_requiresBuild.erase(requiredIter); + } + + if (!BuildQueueContainsProject(projectInfo.m_path)) + { + if (m_buildQueue.empty() && !m_currentBuilder) + { + StartProjectBuild(projectInfo); + } + else + { + m_buildQueue.append(projectInfo); + } } } @@ -331,17 +471,7 @@ namespace O3DE::ProjectManager } else { - // refresh the projects content by re-creating it for now - if (m_projectsContent) - { - m_stack->removeWidget(m_projectsContent); - m_projectsContent->deleteLater(); - } - - m_projectsContent = CreateProjectsContent(); - - m_stack->addWidget(m_projectsContent); - m_stack->setCurrentWidget(m_projectsContent); + ResetProjectsContent(); } } @@ -363,4 +493,89 @@ namespace O3DE::ProjectManager return displayFirstTimeContent; } + void ProjectsScreen::StartProjectBuild(const ProjectInfo& projectInfo) + { + if (ProjectUtils::IsVS2019Installed()) + { + QMessageBox::StandardButton buildProject = QMessageBox::information( + this, + tr("Building \"%1\"").arg(projectInfo.m_projectName), + tr("Ready to build \"%1\"?").arg(projectInfo.m_projectName), + QMessageBox::No | QMessageBox::Yes); + + if (buildProject == QMessageBox::Yes) + { + m_currentBuilder = new ProjectBuilderController(projectInfo, nullptr, this); + ResetProjectsContent(); + connect(m_currentBuilder, &ProjectBuilderController::Done, this, &ProjectsScreen::ProjectBuildDone); + + m_currentBuilder->Start(); + } + else + { + ProjectBuildDone(); + } + } + } + + void ProjectsScreen::ProjectBuildDone() + { + delete m_currentBuilder; + m_currentBuilder = nullptr; + + if (!m_buildQueue.empty()) + { + StartProjectBuild(m_buildQueue.front()); + m_buildQueue.pop_front(); + } + else + { + ResetProjectsContent(); + } + } + + QList::iterator ProjectsScreen::RequiresBuildProjectIterator(const QString& projectPath) + { + QString nativeProjPath(QDir::toNativeSeparators(projectPath)); + auto projectIter = m_requiresBuild.begin(); + for (; projectIter != m_requiresBuild.end(); ++projectIter) + { + if (QDir::toNativeSeparators(projectIter->m_path) == nativeProjPath) + { + break; + } + } + + return projectIter; + } + + bool ProjectsScreen::BuildQueueContainsProject(const QString& projectPath) + { + QString nativeProjPath(QDir::toNativeSeparators(projectPath)); + for (const ProjectInfo& project : m_buildQueue) + { + if (QDir::toNativeSeparators(project.m_path) == nativeProjPath) + { + return true; + } + } + + return false; + } + + bool ProjectsScreen::WarnIfInBuildQueue(const QString& projectPath) + { + if (BuildQueueContainsProject(projectPath)) + { + QMessageBox::warning( + this, + tr("Action Temporarily Disabled!"), + tr("Action not allowed on projects in build queue.")); + + return true; + } + + return false; + } + } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectsScreen.h b/Code/Tools/ProjectManager/Source/ProjectsScreen.h index e02b34525b..bc28d4ef30 100644 --- a/Code/Tools/ProjectManager/Source/ProjectsScreen.h +++ b/Code/Tools/ProjectManager/Source/ProjectsScreen.h @@ -13,21 +13,28 @@ #if !defined(Q_MOC_RUN) #include +#include + +#include #endif QT_FORWARD_DECLARE_CLASS(QPaintEvent) QT_FORWARD_DECLARE_CLASS(QFrame) QT_FORWARD_DECLARE_CLASS(QStackedWidget) +QT_FORWARD_DECLARE_CLASS(QLayout) namespace O3DE::ProjectManager { + QT_FORWARD_DECLARE_CLASS(ProjectBuilderController); + QT_FORWARD_DECLARE_CLASS(ProjectButton); + class ProjectsScreen : public ScreenWidget { public: explicit ProjectsScreen(QWidget* parent = nullptr); - ~ProjectsScreen() = default; + ~ProjectsScreen(); ProjectManagerScreen GetScreenEnum() override; QString GetTabText() override; @@ -35,6 +42,7 @@ namespace O3DE::ProjectManager protected: void NotifyCurrentScreen() override; + void ProjectBuildDone(); protected slots: void HandleNewProjectButton(); @@ -45,19 +53,32 @@ namespace O3DE::ProjectManager void HandleRemoveProject(const QString& projectPath); void HandleDeleteProject(const QString& projectPath); + void SuggestBuildProject(const ProjectInfo& projectInfo); + void QueueBuildProject(const ProjectInfo& projectInfo); + void paintEvent(QPaintEvent* event) override; private: QFrame* CreateFirstTimeContent(); - QFrame* CreateProjectsContent(); + QFrame* CreateProjectsContent(QString buildProjectPath = "", ProjectButton** projectButton = nullptr); + ProjectButton* CreateProjectButton(ProjectInfo& project, QLayout* flowLayout, bool processing = false); + void ResetProjectsContent(); bool ShouldDisplayFirstTimeContent(); - QAction* m_createNewProjectAction; - QAction* m_addExistingProjectAction; + void StartProjectBuild(const ProjectInfo& projectInfo); + QList::iterator RequiresBuildProjectIterator(const QString& projectPath); + bool BuildQueueContainsProject(const QString& projectPath); + bool WarnIfInBuildQueue(const QString& projectPath); + + QAction* m_createNewProjectAction = nullptr; + QAction* m_addExistingProjectAction = nullptr; QPixmap m_background; - QFrame* m_firstTimeContent; - QFrame* m_projectsContent; - QStackedWidget* m_stack; + QFrame* m_firstTimeContent = nullptr; + QFrame* m_projectsContent = nullptr; + QStackedWidget* m_stack = nullptr; + QList m_requiresBuild; + QQueue m_buildQueue; + ProjectBuilderController* m_currentBuilder = nullptr; const QString m_projectPreviewImagePath = "/preview.png"; diff --git a/Code/Tools/ProjectManager/Source/PythonBindings.cpp b/Code/Tools/ProjectManager/Source/PythonBindings.cpp index 3263505f9e..5f4bb833d8 100644 --- a/Code/Tools/ProjectManager/Source/PythonBindings.cpp +++ b/Code/Tools/ProjectManager/Source/PythonBindings.cpp @@ -667,7 +667,7 @@ namespace O3DE::ProjectManager { ProjectInfo projectInfo; projectInfo.m_path = Py_To_String(path); - projectInfo.m_isNew = false; + projectInfo.m_needsBuild = false; auto projectData = m_manifest.attr("get_project_json_data")(pybind11::none(), path); if (pybind11::isinstance(projectData)) diff --git a/Code/Tools/ProjectManager/Source/ScreenWidget.h b/Code/Tools/ProjectManager/Source/ScreenWidget.h index 2ad6d30201..47baed261c 100644 --- a/Code/Tools/ProjectManager/Source/ScreenWidget.h +++ b/Code/Tools/ProjectManager/Source/ScreenWidget.h @@ -13,6 +13,7 @@ #if !defined(Q_MOC_RUN) #include +#include #include #include @@ -61,6 +62,7 @@ namespace O3DE::ProjectManager void GotoPreviousScreenRequest(); void ResetScreenRequest(ProjectManagerScreen screen); void NotifyCurrentProject(const QString& projectPath); + void NotifyBuildProject(const ProjectInfo& projectInfo); }; diff --git a/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp b/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp index 52fcbf354a..646f66a557 100644 --- a/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp @@ -177,6 +177,7 @@ namespace O3DE::ProjectManager connect(newScreen, &ScreenWidget::GotoPreviousScreenRequest, this, &ScreensCtrl::GotoPreviousScreen); connect(newScreen, &ScreenWidget::ResetScreenRequest, this, &ScreensCtrl::ResetScreen); connect(newScreen, &ScreenWidget::NotifyCurrentProject, this, &ScreensCtrl::NotifyCurrentProject); + connect(newScreen, &ScreenWidget::NotifyBuildProject, this, &ScreensCtrl::NotifyBuildProject); } void ScreensCtrl::ResetAllScreens() diff --git a/Code/Tools/ProjectManager/Source/ScreensCtrl.h b/Code/Tools/ProjectManager/Source/ScreensCtrl.h index 3b51ed529a..841108dff7 100644 --- a/Code/Tools/ProjectManager/Source/ScreensCtrl.h +++ b/Code/Tools/ProjectManager/Source/ScreensCtrl.h @@ -13,6 +13,7 @@ #if !defined(Q_MOC_RUN) #include +#include #include #include @@ -39,6 +40,7 @@ namespace O3DE::ProjectManager signals: void NotifyCurrentProject(const QString& projectPath); + void NotifyBuildProject(const ProjectInfo& projectInfo); public slots: bool ChangeToScreen(ProjectManagerScreen screen); diff --git a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp index a383a0f93b..6fcb1b1c71 100644 --- a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp @@ -119,7 +119,9 @@ namespace O3DE::ProjectManager void UpdateProjectCtrl::HandleNextButton() { - if (m_stack->currentIndex() == ScreenOrder::Settings) + bool shouldRebuild = false; + + if (m_stack->currentIndex() == ScreenOrder::Settings && m_updateSettingsScreen) { if (m_updateSettingsScreen) { @@ -155,11 +157,17 @@ namespace O3DE::ProjectManager m_projectInfo = newProjectSettings; } } - - if (m_stack->currentIndex() == ScreenOrder::Gems && m_gemCatalogScreen) + else if (m_stack->currentIndex() == ScreenOrder::Gems && m_gemCatalogScreen) { // Enable or disable the gems that got adjusted in the gem catalog and apply them to the given project. m_gemCatalogScreen->EnableDisableGemsForProject(m_projectInfo.m_path); + + shouldRebuild = true; + } + + if (shouldRebuild) + { + emit NotifyBuildProject(m_projectInfo); } emit ChangeScreenRequest(ProjectManagerScreen::Projects); diff --git a/Code/Tools/ProjectManager/project_manager_files.cmake b/Code/Tools/ProjectManager/project_manager_files.cmake index 40f450ab6f..eb9cd1145e 100644 --- a/Code/Tools/ProjectManager/project_manager_files.cmake +++ b/Code/Tools/ProjectManager/project_manager_files.cmake @@ -38,6 +38,8 @@ set(FILES Source/ProjectInfo.cpp Source/ProjectUtils.h Source/ProjectUtils.cpp + Source/ProjectBuilder.h + Source/ProjectBuilder.cpp Source/UpdateProjectSettingsScreen.h Source/UpdateProjectSettingsScreen.cpp Source/NewProjectSettingsScreen.h From 9df995dd264516dfd821ca5c51c84400f14f957c Mon Sep 17 00:00:00 2001 From: Ken Pruiksma Date: Fri, 4 Jun 2021 20:57:44 -0500 Subject: [PATCH 08/15] Temporal anti-aliasing and constrast adaptive sharpening (#1161) First version of temporal antialiasing and contrast adaptive sharpening for GA. Works well in most cases but still has a few issues that will need additional time. This is only the passes and shaders with no exposure to the editor. TAA and CAS can be turned on by enabling their respective passes in the pipeline. All of the code has been previously reviewed in smaller PRs into the taa_staging branch: aws-lumberyard-dev#29 aws-lumberyard-dev#53 aws-lumberyard-dev#73 aws-lumberyard-dev#79 aws-lumberyard-dev#84 Main issues: - Bloom doesn't play nice with TAA and seems to greatly amplify any flickering - AuxGeom jitters with the camera, so TAA doesn't currently work well in editor - Transparencies don't have correct motion vectors. History rectification keeps this from looking too bad, but could still be improved - There is still more that could be done to inhibit flickering, usually from specular aliasing - Motion vectors aren't correct on POM unless PDO is turned on, which can result in some blurring during motion. - SSAO can contribute to flickering in its default half res configuration. Changing this to full res mitigates the problem. Squashed merge of the following: * [ATOM-13987] Initial checkin of Taa pass. * TAA pass setup WIP. (does not work yet due to pass configuration issues). * Taa WIP - Camera motion vectors fixed and hooked up. TAA does simple reprojection and rejection based on depth. * Small update to use lerp and add some comments. * Fix issue with attachments not being set up on bindings at initialization. Fixing issue with half-pixel offsets in TAA shader * - Motion vector passes now use the same output with mesh motion vectors overwriting camera motion vectors. - Taa pass now works with multiple pipelines. - Cleaned up TAA shader a bit. * Fixes from PR review. * Adding check for multiple attachments of the same name with different resources in Pass::ImportAttachments(). * Adding camera jitter with configurable position count. Updated TAA to blend in tonemapped space. * Fixes from PR review. Fixing camera motion vectors for background (infinite distance) * Updates to taa shader from PR review * Adding a rcp input color size. * Fix comment on PassAttachment::Update() * Updates for PR review. * Fixing missing const on the FrameAttachment* in Pass's call to FindAttachment() * Taa WIP - Adding filtering to both the current pixel and history. Adding rectification based on variance clipping. Adding some basic anti-flickering. Removing rejection based on depth. * Updates from PR code review. Mostly better commenting and naming. * Adding contrast adaptive sharpening based on AMD FidelityFX CAS to help with the softness added by TAA. * Changing to using luminance for sharpening instead of just green. Added some comments. * Moving Taa's NaN check to a better location. Disabling TAA and sharpening in prep for check in. * Updates from PR feedback. --- .../Passes/ContrastAdaptiveSharpening.pass | 75 +++++ .../Common/Assets/Passes/MainPipeline.pass | 7 + .../Assets/Passes/MeshMotionVector.pass | 39 +-- .../Assets/Passes/MotionVectorParent.pass | 20 ++ .../Assets/Passes/PassTemplates.azasset | 8 + .../Assets/Passes/PostProcessParent.pass | 52 +++- .../Passes/SMAA1xApplyLinearHDRColor.pass | 6 + .../Feature/Common/Assets/Passes/Taa.pass | 113 ++++++++ .../MotionVector/CameraMotionVector.azsl | 21 +- .../MotionVector/MeshMotionVectorCommon.azsli | 4 + .../ContrastAdaptiveSharpening.azsl | 85 ++++++ .../ContrastAdaptiveSharpening.shader | 11 + .../Assets/Shaders/PostProcessing/Taa.azsl | 271 ++++++++++++++++++ .../Assets/Shaders/PostProcessing/Taa.shader | 11 + .../atom_feature_common_asset_files.cmake | 2 + .../Code/Source/CommonSystemComponent.cpp | 5 + .../Code/Source/PostProcessing/TaaPass.cpp | 247 ++++++++++++++++ .../Code/Source/PostProcessing/TaaPass.h | 105 +++++++ .../Code/atom_feature_common_files.cmake | 2 + .../Atom/RHI/FrameGraphAttachmentInterface.h | 6 + .../Code/Include/Atom/RPI.Public/Pass/Pass.h | 4 +- .../Atom/RPI.Public/Pass/PassAttachment.h | 3 +- .../RPI/Code/Include/Atom/RPI.Public/View.h | 16 +- .../RPI/Code/Source/RPI.Public/Pass/Pass.cpp | 29 +- .../Source/RPI.Public/Pass/PassAttachment.cpp | 4 +- Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp | 83 +++--- 26 files changed, 1138 insertions(+), 91 deletions(-) create mode 100644 Gems/Atom/Feature/Common/Assets/Passes/ContrastAdaptiveSharpening.pass create mode 100644 Gems/Atom/Feature/Common/Assets/Passes/Taa.pass create mode 100644 Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/ContrastAdaptiveSharpening.azsl create mode 100644 Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/ContrastAdaptiveSharpening.shader create mode 100644 Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/Taa.azsl create mode 100644 Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/Taa.shader create mode 100644 Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.cpp create mode 100644 Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.h diff --git a/Gems/Atom/Feature/Common/Assets/Passes/ContrastAdaptiveSharpening.pass b/Gems/Atom/Feature/Common/Assets/Passes/ContrastAdaptiveSharpening.pass new file mode 100644 index 0000000000..44ab6f4a52 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Passes/ContrastAdaptiveSharpening.pass @@ -0,0 +1,75 @@ +{ + "Type": "JsonSerialization", + "Version": 1, + "ClassName": "PassAsset", + "ClassData": { + "PassTemplate": { + "Name": "ContrastAdaptiveSharpeningTemplate", + "PassClass": "ComputePass", + "Slots": [ + { + "Name": "InputColor", + "SlotType": "Input", + "ShaderInputName": "m_inputColor", + "ScopeAttachmentUsage": "Shader" + }, + { + "Name": "OutputColor", + "SlotType": "Output", + "ShaderInputName": "m_outputColor", + "ScopeAttachmentUsage": "Shader" + } + ], + "ImageAttachments": [ + { + "Name": "Output", + "FormatSource": { + "Pass": "This", + "Attachment": "InputColor" + }, + "SizeSource": { + "Source": { + "Pass": "This", + "Attachment": "InputColor" + } + }, + "ImageDescriptor": { + "Format": "R16G16B16A16_FLOAT", + "BindFlags": "3", + "SharedQueueMask": "1" + } + } + ], + "Connections": [ + { + "LocalSlot": "OutputColor", + "AttachmentRef": { + "Pass": "This", + "Attachment": "Output" + } + } + ], + "FallbackConnections": [ + { + "Input": "InputColor", + "Output": "OutputColor" + } + ], + "PassData": { + "$type": "ComputePassData", + "ShaderAsset": { + "FilePath": "Shaders/Postprocessing/ContrastAdaptiveSharpening.shader" + }, + "Make Fullscreen Pass": true, + "ShaderDataMappings": { + "FloatMappings": [ + { + "Name": "m_strength", + "Value": 0.25 + } + ] + } + } + } + } +} diff --git a/Gems/Atom/Feature/Common/Assets/Passes/MainPipeline.pass b/Gems/Atom/Feature/Common/Assets/Passes/MainPipeline.pass index af7408b48c..b2e0cf088e 100644 --- a/Gems/Atom/Feature/Common/Assets/Passes/MainPipeline.pass +++ b/Gems/Atom/Feature/Common/Assets/Passes/MainPipeline.pass @@ -341,6 +341,13 @@ "Attachment": "Depth" } }, + { + "LocalSlot": "MotionVectors", + "AttachmentRef": { + "Pass": "MotionVectorPass", + "Attachment": "MotionVectorOutput" + } + }, { "LocalSlot": "SwapChainOutput", "AttachmentRef": { diff --git a/Gems/Atom/Feature/Common/Assets/Passes/MeshMotionVector.pass b/Gems/Atom/Feature/Common/Assets/Passes/MeshMotionVector.pass index 57600440b4..4c14fd9b3f 100644 --- a/Gems/Atom/Feature/Common/Assets/Passes/MeshMotionVector.pass +++ b/Gems/Atom/Feature/Common/Assets/Passes/MeshMotionVector.pass @@ -13,22 +13,11 @@ "SlotType": "Input", "ScopeAttachmentUsage": "InputAssembly" }, - // Outputs... + // Input/Output... { - "Name": "Output", - "SlotType": "Output", - "ScopeAttachmentUsage": "RenderTarget", - "LoadStoreAction": { - "ClearValue": { - "Value": [ - 0.0, - 0.0, - 0.0, - {} - ] - }, - "LoadAction": "Clear" - } + "Name": "MotionInputOutput", + "SlotType": "InputOutput", + "ScopeAttachmentUsage": "RenderTarget" }, { "Name": "OutputDepthStencil", @@ -46,19 +35,6 @@ } ], "ImageAttachments": [ - { - "Name": "MotionBuffer", - "SizeSource": { - "Source": { - "Pass": "Parent", - "Attachment": "SwapChainOutput" - } - }, - "ImageDescriptor": { - "Format": "R16G16_FLOAT", - "SharedQueueMask": "Graphics" - } - }, { "Name": "DepthStencil", "SizeSource": { @@ -74,13 +50,6 @@ } ], "Connections": [ - { - "LocalSlot": "Output", - "AttachmentRef": { - "Pass": "This", - "Attachment": "MotionBuffer" - } - }, { "LocalSlot": "OutputDepthStencil", "AttachmentRef": { diff --git a/Gems/Atom/Feature/Common/Assets/Passes/MotionVectorParent.pass b/Gems/Atom/Feature/Common/Assets/Passes/MotionVectorParent.pass index a8369e4618..d7f4894706 100644 --- a/Gems/Atom/Feature/Common/Assets/Passes/MotionVectorParent.pass +++ b/Gems/Atom/Feature/Common/Assets/Passes/MotionVectorParent.pass @@ -20,6 +20,19 @@ { "Name": "SwapChainOutput", "SlotType": "InputOutput" + }, + { + "Name": "MotionVectorOutput", + "SlotType": "Output" + } + ], + "Connections": [ + { + "LocalSlot": "MotionVectorOutput", + "AttachmentRef": { + "Pass": "MeshMotionVectorPass", + "Attachment": "MotionInputOutput" + } } ], "PassRequests": [ @@ -50,6 +63,13 @@ "Pass": "Parent", "Attachment": "SkinnedMeshes" } + }, + { + "LocalSlot": "MotionInputOutput", + "AttachmentRef": { + "Pass": "CameraMotionVectorPass", + "Attachment": "Output" + } } ], "PassData": { diff --git a/Gems/Atom/Feature/Common/Assets/Passes/PassTemplates.azasset b/Gems/Atom/Feature/Common/Assets/Passes/PassTemplates.azasset index c56e8932b1..702ac8fe72 100644 --- a/Gems/Atom/Feature/Common/Assets/Passes/PassTemplates.azasset +++ b/Gems/Atom/Feature/Common/Assets/Passes/PassTemplates.azasset @@ -284,6 +284,14 @@ "Name": "SMAA1xApplyPerceptualColorTemplate", "Path": "Passes/SMAA1xApplyPerceptualColor.pass" }, + { + "Name": "TaaTemplate", + "Path": "Passes/Taa.pass" + }, + { + "Name": "ContrastAdaptiveSharpeningTemplate", + "Path": "Passes/ContrastAdaptiveSharpening.pass" + }, { "Name": "SsaoParentTemplate", "Path": "Passes/SsaoParent.pass" diff --git a/Gems/Atom/Feature/Common/Assets/Passes/PostProcessParent.pass b/Gems/Atom/Feature/Common/Assets/Passes/PostProcessParent.pass index 36f7f1e985..fb27770da3 100644 --- a/Gems/Atom/Feature/Common/Assets/Passes/PostProcessParent.pass +++ b/Gems/Atom/Feature/Common/Assets/Passes/PostProcessParent.pass @@ -16,6 +16,10 @@ "Name": "Depth", "SlotType": "Input" }, + { + "Name": "MotionVectors", + "SlotType": "Input" + }, // SwapChain here is only used to reference the frame height and format { "Name": "SwapChainOutput", @@ -40,8 +44,8 @@ { "LocalSlot": "Output", "AttachmentRef": { - "Pass": "LightAdaptation", - "Attachment": "Output" + "Pass": "ContrastAdaptiveSharpeningPass", + "Attachment": "OutputColor" } }, { @@ -80,6 +84,34 @@ } ] }, + { + "Name": "TaaPass", + "TemplateName": "TaaTemplate", + "Enabled": false, + "Connections": [ + { + "LocalSlot": "InputColor", + "AttachmentRef": { + "Pass": "SMAA1xApplyLinearHDRColorPass", + "Attachment": "OutputColor" + } + }, + { + "LocalSlot": "InputDepth", + "AttachmentRef": { + "Pass": "Parent", + "Attachment": "Depth" + } + }, + { + "LocalSlot": "MotionVectors", + "AttachmentRef": { + "Pass": "Parent", + "Attachment": "MotionVectors" + } + } + ] + }, { "Name": "DepthOfFieldPass", "TemplateName": "DepthOfFieldTemplate", @@ -88,7 +120,7 @@ { "LocalSlot": "DoFColorInput", "AttachmentRef": { - "Pass": "SMAA1xApplyLinearHDRColorPass", + "Pass": "TaaPass", "Attachment": "OutputColor" } }, @@ -134,6 +166,20 @@ } } ] + }, + { + "Name": "ContrastAdaptiveSharpeningPass", + "TemplateName": "ContrastAdaptiveSharpeningTemplate", + "Enabled": false, + "Connections": [ + { + "LocalSlot": "InputColor", + "AttachmentRef": { + "Pass": "LightAdaptation", + "Attachment": "Output" + } + } + ] } ] } diff --git a/Gems/Atom/Feature/Common/Assets/Passes/SMAA1xApplyLinearHDRColor.pass b/Gems/Atom/Feature/Common/Assets/Passes/SMAA1xApplyLinearHDRColor.pass index 98700d5f0c..70604fba25 100644 --- a/Gems/Atom/Feature/Common/Assets/Passes/SMAA1xApplyLinearHDRColor.pass +++ b/Gems/Atom/Feature/Common/Assets/Passes/SMAA1xApplyLinearHDRColor.pass @@ -40,6 +40,12 @@ } } ], + "FallbackConnections": [ + { + "Input": "InputColor", + "Output": "OutputColor" + } + ], "PassRequests": [ { "Name": "SMAAConvertToPerceptualColor", diff --git a/Gems/Atom/Feature/Common/Assets/Passes/Taa.pass b/Gems/Atom/Feature/Common/Assets/Passes/Taa.pass new file mode 100644 index 0000000000..f1ba156007 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Passes/Taa.pass @@ -0,0 +1,113 @@ +{ + "Type": "JsonSerialization", + "Version": 1, + "ClassName": "PassAsset", + "ClassData": { + "PassTemplate": { + "Name": "TaaTemplate", + "PassClass": "TaaPass", + "Slots": [ + { + "Name": "InputColor", + "SlotType": "Input", + "ShaderInputName": "m_inputColor", + "ScopeAttachmentUsage": "Shader" + }, + { + "Name": "InputDepth", + "SlotType": "Input", + "ShaderInputName": "m_inputDepth", + "ScopeAttachmentUsage": "Shader" + }, + { + "Name": "MotionVectors", + "SlotType": "Input", + "ShaderInputName": "m_motionVectors", + "ScopeAttachmentUsage": "Shader" + }, + { + "Name": "LastFrameAccumulation", + "SlotType": "Input", + "ShaderInputName": "m_lastFrameAccumulation", + "ScopeAttachmentUsage": "Shader" + }, + { + "Name": "OutputColor", + "SlotType": "Output", + "ShaderInputName": "m_outputColor", + "ScopeAttachmentUsage": "Shader" + } + ], + "ImageAttachments": [ + { + "Name": "Accumulation1", + "Lifetime": "Imported", + "FormatSource": { + "Pass": "This", + "Attachment": "InputColor" + }, + "SizeSource": { + "Source": { + "Pass": "This", + "Attachment": "InputColor" + } + }, + "ImageDescriptor": { + "Format": "R16G16B16A16_FLOAT", + "BindFlags": "3", + "SharedQueueMask": "1" + } + }, + { + "Name": "Accumulation2", + "Lifetime": "Imported", + "FormatSource": { + "Pass": "This", + "Attachment": "InputColor" + }, + "SizeSource": { + "Source": { + "Pass": "This", + "Attachment": "InputColor" + } + }, + "ImageDescriptor": { + "Format": "R16G16B16A16_FLOAT", + "BindFlags": "3", + "SharedQueueMask": "1" + } + } + ], + "FallbackConnections": [ + { + "Input": "InputColor", + "Output": "OutputColor" + } + ], + "PassData": { + "$type": "TaaPassData", + "ShaderAsset": { + "FilePath": "Shaders/Postprocessing/Taa.shader" + }, + "Make Fullscreen Pass": true, + "ShaderDataMappings": { + "FloatMappings": [ + { + "Name": "m_currentFrameContribution", + "Value": 0.1 + }, + { + "Name": "m_clampGamma", + "Value": 1.0 + }, + { + "Name": "m_maxDeviationBeforeDampening", + "Value": 0.5 + } + ] + }, + "NumJitterPositions": 16 + } + } + } +} diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/MotionVector/CameraMotionVector.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/MotionVector/CameraMotionVector.azsl index a073f42f03..c83e5138e6 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/MotionVector/CameraMotionVector.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/MotionVector/CameraMotionVector.azsl @@ -39,10 +39,27 @@ PSOutput MainPS(VSOutput IN) PSOutput OUT; float depth = PassSrg::m_depthStencil.Sample(PassSrg::LinearSampler, IN.m_texCoord).r; + + // If depth is 0, that means depth is on the far plane. This should be treated as being infinitely far + // away, not actually on the far plane, because the infinitely far background shouldn't move as a result + // of camera translation. Tweaking the depth to -near/far distance makes that happen. Keep in mind near + // and far are inverted, so this normally a very small value. + if (depth == 0.0) + { + depth = -ViewSrg::GetFarZ() / ViewSrg::GetNearZ(); + } + float2 clipPos = float2(mad(IN.m_texCoord.x, 2.0, -1.0), mad(IN.m_texCoord.y, -2.0, 1.0)); float4 worldPos = mul(ViewSrg::m_viewProjectionInverseMatrix, float4(clipPos, depth, 1.0)); + float4 clipPosPrev = mul(ViewSrg::m_viewProjectionPrevMatrix, float4((worldPos / worldPos.w).xyz, 1.0)); - - OUT.m_motion = (clipPos - (clipPosPrev / clipPosPrev.w).xy) * 0.5; + clipPosPrev = (clipPosPrev / clipPosPrev.w); + + // Clip space is from -1.0 to 1.0, so the motion vectors are 2x as big as they should be + OUT.m_motion = (clipPos - clipPosPrev.xy) * 0.5; + + // Flip y to line up with uv coordinates + OUT.m_motion.y = -OUT.m_motion.y; + return OUT; } diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/MotionVector/MeshMotionVectorCommon.azsli b/Gems/Atom/Feature/Common/Assets/Shaders/MotionVector/MeshMotionVectorCommon.azsli index c11e9d9e0e..ff2758af87 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/MotionVector/MeshMotionVectorCommon.azsli +++ b/Gems/Atom/Feature/Common/Assets/Shaders/MotionVector/MeshMotionVectorCommon.azsli @@ -41,5 +41,9 @@ PSOutput MainPS(VSOutput IN) float2 motion = (clipPos.xy / clipPos.w - clipPosPrev.xy / clipPosPrev.w) * 0.5; OUT.m_motion = motion; + + // Flip y to line up with uv coordinates + OUT.m_motion.y = -OUT.m_motion.y; + return OUT; } diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/ContrastAdaptiveSharpening.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/ContrastAdaptiveSharpening.azsl new file mode 100644 index 0000000000..14fa942a7d --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/ContrastAdaptiveSharpening.azsl @@ -0,0 +1,85 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include +#include + +#define TILE_DIM_X 16 +#define TILE_DIM_Y 16 + +ShaderResourceGroup PassSrg : SRG_PerPass +{ + Texture2D m_inputColor; + RWTexture2D m_outputColor; + + float m_strength; // Strength of the sharpening effect. Range from 0 to 1. +} + + +// Constrast Adaptive Sharpening, based on AMD FidelityFX CAS - https://gpuopen.com/fidelityfx-cas/ + +// This shader sharpens the input based on the contrast of the local neighborhood +// so that only areas that need sharpening are sharpened, while high constast areas +// are mostly left alone. + +[numthreads(TILE_DIM_X, TILE_DIM_Y, 1)] +void MainCS( + uint3 dispatchThreadID : SV_DispatchThreadID, + uint3 groupID : SV_GroupID, + uint groupIndex : SV_GroupIndex) +{ + uint2 pixelCoord = dispatchThreadID.xy; + + // Fetch local neighborhood to determin sharpening weight. + // a + // b c d + // e + + float3 sampleA = PassSrg::m_inputColor[pixelCoord + int2( 0, -1)].rgb; + float3 sampleB = PassSrg::m_inputColor[pixelCoord + int2(-1, 0)].rgb; + float3 sampleC = PassSrg::m_inputColor[pixelCoord + int2( 0, 0)].rgb; + float3 sampleD = PassSrg::m_inputColor[pixelCoord + int2( 1, 0)].rgb; + float3 sampleE = PassSrg::m_inputColor[pixelCoord + int2( 0, 1)].rgb; + + float lumA = GetLuminance(sampleA); + float lumB = GetLuminance(sampleB); + float lumC = GetLuminance(sampleC); + float lumD = GetLuminance(sampleD); + float lumE = GetLuminance(sampleE); + + // Get the min and max. Just use the green channel for luminance. + float minLum = min(min(lumA, lumB), min(lumC, min(lumD, lumE))); + float maxLum = max(max(lumA, lumB), max(lumC, max(lumD, lumE))); + + float dMinLum = minLum; // Distance from 0 to minimum + float dMaxLum = 1.0 - maxLum; // Distance from 1 to the maximum + + // baseSharpening is higher when local contrast is lower to avoid over-sharpening. + float baseSharpening = min(dMinLum, dMaxLum) / max(maxLum, 0.0001); + baseSharpening = sqrt(baseSharpening); // bias towards more sharpening + + // Negative weights for sharpening effect, center pixel is always weighted 1. + float developerMaximum = lerp(-0.125, -0.2, PassSrg::m_strength); + float weight = baseSharpening * developerMaximum; + float totalWeight = weight * 4 + 1.0; + + float3 output = + ( + sampleA * weight + + sampleB * weight + + sampleC + + sampleD * weight + + sampleE * weight + ) / totalWeight; + + PassSrg::m_outputColor[pixelCoord] = float4(output, 1.0); +} diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/ContrastAdaptiveSharpening.shader b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/ContrastAdaptiveSharpening.shader new file mode 100644 index 0000000000..756ce0ec7a --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/ContrastAdaptiveSharpening.shader @@ -0,0 +1,11 @@ +{ + "Source": "ContrastAdaptiveSharpening", + "ProgramSettings": { + "EntryPoints": [ + { + "name": "MainCS", + "type": "Compute" + } + ] + } +} diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/Taa.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/Taa.azsl new file mode 100644 index 0000000000..94944df9de --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/Taa.azsl @@ -0,0 +1,271 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include +#include + +#define TILE_DIM_X 16 +#define TILE_DIM_Y 16 + +ShaderResourceGroup PassSrg : SRG_PerPass +{ + Texture2D m_inputColor; + Texture2D m_inputDepth; + Texture2D m_motionVectors; + Texture2D m_lastFrameAccumulation; + + RWTexture2D m_outputColor; + + Sampler LinearSampler + { + MinFilter = Linear; + MagFilter = Linear; + MipFilter = Linear; + AddressU = Clamp; + AddressV = Clamp; + AddressW = Clamp; + }; + + // Current frame's default contribution to the history. + float m_currentFrameContribution; + + // Increase this value for weaker clamping, decrease for stronger clamping, default 1.0. + float m_clampGamma; + + // Default 0.5, used for flicker reduction. Any sample further than this many standard deviations outside the neighborhood + // will have its weight decreased. The further outside the max deviation, the more its weight is reduced. + float m_maxDeviationBeforeDampening; + + struct Constants + { + uint2 m_inputColorSize; + float2 m_inputColorRcpSize; + + // 3x3 filter weights + // 8 2 6 + // 3 0 1 + // 7 4 5 + float4 m_weights1; // 0 1 2 3 + float4 m_weights2; // 4 5 6 7 + float4 m_weights3; // 8 x x x + }; + Constants m_constantData; +} + +static const int2 offsets[9] = +{ + // Center + int2(0, 0), + // Cross + int2( 1, 0), + int2( 0,-1), + int2(-1, 0), + int2( 0, 1), + // Diagonals + int2( 1,-1), + int2( 1, 1), + int2(-1,-1), + int2(-1, 1), +}; + +float3 RgbToYCoCg(float3 rgb) +{ + const float3x3 conversionMatrix = + { + 0.25, 0.50, 0.25, + 0.50, 0.00, -0.50, + -0.25, 0.50, -0.25 + }; + return mul(conversionMatrix, rgb); +} + +float3 YCoCgToRgb(float3 yCoCg) +{ + const float3x3 conversionMatrix = + { + 1.0, 1.0, -1.0, + 1.0, 0.0, 1.0, + 1.0, -1.0, -1.0 + }; + return mul(conversionMatrix, yCoCg); +} + +// Sample a texture with a 5 tap Catmull-Rom. Consider ripping this out and putting in a more general location. +// This function samples a 4x4 neighborhood around the uv. By taking advantage of bilinear filtering this can be +// done with only 9 taps on the edges between pixels. The cost is further reduced by dropping the 4 diagonal +// samples as their influence is negligible. +float4 SampleCatmullRom5Tap(Texture2D texture, SamplerState linearSampler, float2 uv, float2 textureSize, float2 rcpTextureSize, float sharpness) +{ + // Think of sample locations in the 4x4 neighborhood as having a top left coordinate of 0,0 and + // a bottom right coordinate of 3,3. + + // Find the position in texture space then round it to get the center of the 1,1 pixel (tc1) + float2 texelPos = uv * textureSize; + float2 tc1= floor(texelPos - 0.5) + 0.5; + + // Offset from center position to texel + float2 f = texelPos - tc1; + + // Compute Catmull-Rom weights based on the offset and sharpness + float c = sharpness; + float2 w0 = f * (-c + f * (2.0 * c - c * f)); + float2 w1 = 1.0 + f * f * (c -3.0 + (2.0 - c) * f); + float2 w2 = f * (c + f * ((3.0 - 2.0 * c) - (2.0 - c) * f)); + float2 w3 = f * f * (c * f - c); + + float2 w12 = w1 + w2; + + // Compute uv coordinates for sampling the texture + float2 tc0 = (tc1 - 1.0f) * rcpTextureSize; + float2 tc3 = (tc1 + 2.0f) * rcpTextureSize; + float2 tc12 = (tc1 + w2 / w12) * rcpTextureSize; + + // Compute sample weights + float sw0 = w12.x * w0.y; + float sw1 = w0.x * w12.y; + float sw2 = w12.x * w12.y; + float sw3 = w3.x * w12.y; + float sw4 = w12.x * w3.y; + + // total weight of samples to normalize result. + float totalWeight = sw0 + sw1 + sw2 + sw3 + sw4; + + float4 result = 0.0f; + result += texture.SampleLevel(linearSampler, float2(tc12.x, tc0.y), 0.0) * sw0; + result += texture.SampleLevel(linearSampler, float2( tc0.x, tc12.y), 0.0) * sw1; + result += texture.SampleLevel(linearSampler, float2(tc12.x, tc12.y), 0.0) * sw2; + result += texture.SampleLevel(linearSampler, float2( tc3.x, tc12.y), 0.0) * sw3; + result += texture.SampleLevel(linearSampler, float2(tc12.x, tc3.y), 0.0) * sw4; + + return result / totalWeight; +} + +[numthreads(TILE_DIM_X, TILE_DIM_Y, 1)] +void MainCS( + uint3 dispatchThreadID : SV_DispatchThreadID, + uint3 groupID : SV_GroupID, + uint groupIndex : SV_GroupIndex) +{ + uint2 pixelCoord = dispatchThreadID.xy; + + const float filterWeights[9] = + { + PassSrg::m_constantData.m_weights1.x, + PassSrg::m_constantData.m_weights1.y, + PassSrg::m_constantData.m_weights1.z, + PassSrg::m_constantData.m_weights1.w, + PassSrg::m_constantData.m_weights2.x, + PassSrg::m_constantData.m_weights2.y, + PassSrg::m_constantData.m_weights2.z, + PassSrg::m_constantData.m_weights2.w, + PassSrg::m_constantData.m_weights3.x, + }; + + float3 sum = 0.0; + float3 sumOfSquares = 0.0; + float nearestDepth = 1.0; + uint2 nearestDepthPixelCoord; + + float3 thisFrameColor = float3(0.0, 0.0, 0.0); + + // Sample the neighborhood to filter the current pixel, gather statistics about + // its neighbors, and find the closest neighbor to choose a motion vector. + [unroll] for (int i = 0; i < 9; ++i) + { + uint2 neighborhoodPixelCoord = pixelCoord + offsets[i]; + float3 neighborhoodColor = PassSrg::m_inputColor[neighborhoodPixelCoord].rgb; + + // Convert to YCoCg space for better clipping. + neighborhoodColor = RgbToYCoCg(neighborhoodColor); + + sum += neighborhoodColor; + sumOfSquares += neighborhoodColor * neighborhoodColor; + thisFrameColor += neighborhoodColor * filterWeights[i]; + + // Find the coordinate of the nearest depth + float neighborhoodDepth = PassSrg::m_inputDepth[neighborhoodPixelCoord].r; + if (neighborhoodDepth < nearestDepth) + { + nearestDepth = neighborhoodDepth; + nearestDepthPixelCoord = neighborhoodPixelCoord; + } + } + + // Variance clipping, see http://developer.download.nvidia.com/gameworks/events/GDC2016/msalvi_temporal_supersampling.pdf + float3 mean = sum / 9.0; + float3 standardDeviation = max(0.0, sqrt(sumOfSquares / 9.0 - mean * mean)); + standardDeviation *= PassSrg::m_clampGamma; + + // Grab the motion vector from the closest pixel in the 3x3 neighborhood. This is done so that motion vectors correctly + // track edges. For instance, if a pixel lies on the edge of a moving object, where the color is a blend of the + // forground and background, it's possible for the pixel center to hit the (not moving) background. However, the correct + // history for this pixel will be the location this edge was the previous frame. By choosing the motion of the nearest + // pixel in the neighborhood that edge will be correctly tracked. + + // Motion vectors store the direction of movement, so to look up where things were in the previous frame, it's negated. + float2 previousPositionOffset = -PassSrg::m_motionVectors[nearestDepthPixelCoord]; + + // Get the uv coordinate for the previous frame. + float2 rcpSize = PassSrg::m_constantData.m_inputColorRcpSize; + float2 uvCoord = (pixelCoord + 0.5f) * rcpSize; + float2 uvOld = uvCoord + previousPositionOffset; + float2 previousPositionOffsetInPixels = float2(PassSrg::m_constantData.m_inputColorSize) * previousPositionOffset; + + // Sample the last frame using a 5-tap Catmull-Rom + float3 lastFrameColor = SampleCatmullRom5Tap(PassSrg::m_lastFrameAccumulation, PassSrg::LinearSampler, uvOld, PassSrg::m_constantData.m_inputColorSize, PassSrg::m_constantData.m_inputColorRcpSize, 0.5).rgb; + lastFrameColor = RgbToYCoCg(lastFrameColor); + + // Last frame color relative to mean + float3 centerColorOffset = lastFrameColor - mean; + float3 colorOffsetStandardDeviationRatio = abs(standardDeviation / centerColorOffset); + + // Clamp the color by the aabb of the standardDeviation. Can never be greater than 1, so will always be inside or on the bounds of the aabb. + float clampedColorLength = min(min(min(1, colorOffsetStandardDeviationRatio.x), colorOffsetStandardDeviationRatio.y), colorOffsetStandardDeviationRatio.z); + + // Calculate the true clamped color by offsetting it back from the mean. + float3 lastFrameClampedColor = mean + centerColorOffset * clampedColorLength; + + // Anti-flickering - Reduce current frame weight the more it deviates from the history based on the standard deviation of the neighborhood. + // Start reducing weight at differences greater than m_maxDeviationBeforeDampening standard deviations in luminance. + float standardDeviationWeight = standardDeviation.r * PassSrg::m_maxDeviationBeforeDampening; + float3 sdFromLastFrame = standardDeviationWeight / abs(lastFrameClampedColor.r - thisFrameColor.r); + + float currentFrameWeight = PassSrg::m_currentFrameContribution; + currentFrameWeight *= saturate(sdFromLastFrame * sdFromLastFrame); + + // Back to Rgb space + thisFrameColor = YCoCgToRgb(thisFrameColor); + lastFrameClampedColor = YCoCgToRgb(lastFrameClampedColor); + + // Out of bounds protection. + if (any(uvOld > 1.0) || any(uvOld < 0.0)) + { + currentFrameWeight = 1.0f; + } + + // Blend should be in perceptual space, so tonemap first + float luminance = GetLuminance(thisFrameColor); + thisFrameColor = thisFrameColor / (1 + luminance); + lastFrameClampedColor = lastFrameClampedColor / (1 + luminance); + + // Blend color with history + float3 color = lerp(lastFrameClampedColor, thisFrameColor, currentFrameWeight); + + // Un-tonemap color + color = color * (1.0 + luminance); + + // NaN protection (without this NaNs could get in the history buffer and quickly consume the frame) + color = max(0.0, color); + + PassSrg::m_outputColor[pixelCoord].rgb = color; + +} diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/Taa.shader b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/Taa.shader new file mode 100644 index 0000000000..f30ff92f20 --- /dev/null +++ b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/Taa.shader @@ -0,0 +1,11 @@ +{ + "Source": "Taa", + "ProgramSettings": { + "EntryPoints": [ + { + "name": "MainCS", + "type": "Compute" + } + ] + } +} diff --git a/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake b/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake index a9ba765329..3dfabc586a 100644 --- a/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake +++ b/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake @@ -89,6 +89,7 @@ set(FILES Passes/CascadedShadowmaps.pass Passes/CheckerboardResolveColor.pass Passes/CheckerboardResolveDepth.pass + Passes/ContrastAdaptiveSharpening.pass Passes/ConvertToAcescg.pass Passes/DebugOverlayParent.pass Passes/DeferredFog.pass @@ -207,6 +208,7 @@ set(FILES Passes/SsaoHalfRes.pass Passes/SsaoParent.pass Passes/SubsurfaceScattering.pass + Passes/Taa.pass Passes/Transparent.pass Passes/TransparentParent.pass Passes/UI.pass diff --git a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp index d38db1b08e..af28624357 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -133,6 +134,7 @@ namespace AZ PostProcessFeatureProcessor::Reflect(context); ImGuiPassData::Reflect(context); RayTracingPassData::Reflect(context); + TaaPassData::Reflect(context); LightingPreset::Reflect(context); ModelPreset::Reflect(context); @@ -230,6 +232,9 @@ namespace AZ // Add Depth Downsample/Upsample passes passSystem->AddPassCreator(Name("DepthUpsamplePass"), &DepthUpsamplePass::Create); + + // Add Taa Pass + passSystem->AddPassCreator(Name("TaaPass"), &TaaPass::Create); // Add DepthOfField pass passSystem->AddPassCreator(Name("DepthOfFieldCompositePass"), &DepthOfFieldCompositePass::Create); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.cpp new file mode 100644 index 0000000000..9f885ede70 --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.cpp @@ -0,0 +1,247 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace AZ::Render +{ + + RPI::Ptr TaaPass::Create(const RPI::PassDescriptor& descriptor) + { + RPI::Ptr pass = aznew TaaPass(descriptor); + return pass; + } + + TaaPass::TaaPass(const RPI::PassDescriptor& descriptor) + : Base(descriptor) + { + uint32_t numJitterPositions = 8; + + const TaaPassData* taaPassData = RPI::PassUtils::GetPassData(descriptor); + if (taaPassData) + { + numJitterPositions = taaPassData->m_numJitterPositions; + } + + // The coprimes 2, 3 are commonly used for halton sequences because they have an even distribution even for + // few samples. With larger primes you need to offset by some amount between each prime to have the same + // effect. We could allow this to be configurable in the future. + SetupSubPixelOffsets(2, 3, numJitterPositions); + } + + void TaaPass::CompileResources(const RHI::FrameGraphCompileContext& context) + { + struct TaaConstants + { + AZStd::array m_size = { 1, 1 }; + AZStd::array m_rcpSize = { 0.0, 0.0 }; + + AZStd::array m_weights1 = { 0.0 }; + AZStd::array m_weights2 = { 0.0 }; + AZStd::array m_weights3 = { 0.0 }; + }; + + TaaConstants cb; + RHI::Size inputSize = m_lastFrameAccumulationBinding->m_attachment->m_descriptor.m_image.m_size; + cb.m_size[0] = inputSize.m_width; + cb.m_size[1] = inputSize.m_height; + cb.m_rcpSize[0] = 1.0f / inputSize.m_width; + cb.m_rcpSize[1] = 1.0f / inputSize.m_height; + + Offset jitterOffset = m_subPixelOffsets.at(m_offsetIndex); + GenerateFilterWeights(Vector2(jitterOffset.m_xOffset, jitterOffset.m_yOffset)); + cb.m_weights1 = { m_filterWeights[0], m_filterWeights[1], m_filterWeights[2], m_filterWeights[3] }; + cb.m_weights2 = { m_filterWeights[4], m_filterWeights[5], m_filterWeights[6], m_filterWeights[7] }; + cb.m_weights3 = { m_filterWeights[8], 0.0f, 0.0f, 0.0f }; + + m_shaderResourceGroup->SetConstant(m_constantDataIndex, cb); + + + Base::CompileResources(context); + } + + void TaaPass::FrameBeginInternal(FramePrepareParams params) + { + RHI::Size inputSize = m_inputColorBinding->m_attachment->m_descriptor.m_image.m_size; + Vector2 rcpInputSize = Vector2(1.0 / inputSize.m_width, 1.0 / inputSize.m_height); + + RPI::ViewPtr view = GetRenderPipeline()->GetDefaultView(); + m_offsetIndex = (m_offsetIndex + 1) % m_subPixelOffsets.size(); + Offset offset = m_subPixelOffsets.at(m_offsetIndex); + view->SetClipSpaceOffset(offset.m_xOffset * rcpInputSize.GetX(), offset.m_yOffset * rcpInputSize.GetY()); + + m_lastFrameAccumulationBinding->SetAttachment(m_accumulationAttachments[m_accumulationOuptutIndex]); + m_accumulationOuptutIndex ^= 1; // swap which attachment is the output and last frame + + UpdateAttachmentImage(m_accumulationAttachments[m_accumulationOuptutIndex]); + m_outputColorBinding->SetAttachment(m_accumulationAttachments[m_accumulationOuptutIndex]); + + Base::FrameBeginInternal(params); + } + + void TaaPass::ResetInternal() + { + m_accumulationAttachments[0].reset(); + m_accumulationAttachments[1].reset(); + + m_inputColorBinding = nullptr; + m_lastFrameAccumulationBinding = nullptr; + m_outputColorBinding = nullptr; + + Base::ResetInternal(); + } + + void TaaPass::BuildAttachmentsInternal() + { + m_accumulationAttachments[0] = FindAttachment(Name("Accumulation1")); + m_accumulationAttachments[1] = FindAttachment(Name("Accumulation2")); + + bool hasAttachments = m_accumulationAttachments[0] || m_accumulationAttachments[1]; + AZ_Error("TaaPass", hasAttachments, "TaaPass must have Accumulation1 and Accumulation2 ImageAttachments defined."); + + if (hasAttachments) + { + // Make sure the attachments have images when the pass first loads. + for (auto i : { 0, 1 }) + { + if (!m_accumulationAttachments[i]->m_importedResource) + { + UpdateAttachmentImage(m_accumulationAttachments[i]); + } + } + } + + m_inputColorBinding = FindAttachmentBinding(Name("InputColor")); + AZ_Error("TaaPass", m_inputColorBinding, "TaaPass requires a slot for InputColor."); + m_lastFrameAccumulationBinding = FindAttachmentBinding(Name("LastFrameAccumulation")); + AZ_Error("TaaPass", m_lastFrameAccumulationBinding, "TaaPass requires a slot for LastFrameAccumulation."); + m_outputColorBinding = FindAttachmentBinding(Name("OutputColor")); + AZ_Error("TaaPass", m_outputColorBinding, "TaaPass requires a slot for OutputColor."); + + // Set up the attachment for last frame accumulation and output color if it's never been done to + // ensure SRG indices are set up correctly by the pass system. + if (m_lastFrameAccumulationBinding->m_attachment == nullptr) + { + m_lastFrameAccumulationBinding->SetAttachment(m_accumulationAttachments[0]); + m_outputColorBinding->SetAttachment(m_accumulationAttachments[1]); + } + + Base::BuildAttachmentsInternal(); + } + + void TaaPass::UpdateAttachmentImage(RPI::Ptr& attachment) + { + if (!attachment) + { + return; + } + + // update the image attachment descriptor to sync up size and format + attachment->Update(true); + RHI::ImageDescriptor& imageDesc = attachment->m_descriptor.m_image; + RPI::AttachmentImage* currentImage = azrtti_cast(attachment->m_importedResource.get()); + + if (attachment->m_importedResource && imageDesc.m_size == currentImage->GetDescriptor().m_size) + { + // If there's a resource already and the size didn't change, just keep using the old AttachmentImage. + return; + } + + Data::Instance pool = RPI::ImageSystemInterface::Get()->GetSystemAttachmentPool(); + + // set the bind flags + imageDesc.m_bindFlags |= RHI::ImageBindFlags::Color | RHI::ImageBindFlags::ShaderReadWrite; + + // The ImageViewDescriptor must be specified to make sure the frame graph compiler doesn't treat this as a transient image. + RHI::ImageViewDescriptor viewDesc = RHI::ImageViewDescriptor::Create(imageDesc.m_format, 0, 0); + viewDesc.m_aspectFlags = RHI::ImageAspectFlags::Color; + viewDesc.m_overrideBindFlags = RHI::ImageBindFlags::ShaderReadWrite; + + // The full path name is needed for the attachment image so it's not deduplicated from accumulation images in different pipelines. + AZStd::string imageName = RPI::ConcatPassString(GetPathName(), attachment->m_path); + auto attachmentImage = RPI::AttachmentImage::Create(*pool.get(), imageDesc, Name(imageName), nullptr, &viewDesc); + + attachment->m_path = attachmentImage->GetAttachmentId(); + attachment->m_importedResource = attachmentImage; + } + + void TaaPass::SetupSubPixelOffsets(uint32_t haltonX, uint32_t haltonY, uint32_t length) + { + m_subPixelOffsets.resize(length); + HaltonSequence<2> sequence = HaltonSequence<2>({haltonX, haltonY}); + sequence.FillHaltonSequence(m_subPixelOffsets.begin(), m_subPixelOffsets.end()); + + // Adjust to the -1.0 to 1.0 range. This is done because the view needs offsets in clip + // space and is one less calculation that would need to be done in FrameBeginInternal() + AZStd::for_each(m_subPixelOffsets.begin(), m_subPixelOffsets.end(), + [](Offset& offset) + { + offset.m_xOffset = 2.0f * offset.m_xOffset - 1.0f; + offset.m_yOffset = 2.0f * offset.m_yOffset - 1.0f; + } + ); + } + + // Approximation of a Blackman Harris window function of width 3.3. + // https://en.wikipedia.org/wiki/Window_function#Blackman%E2%80%93Harris_window + static float BlackmanHarris(AZ::Vector2 uv) + { + return expf(-2.29f * (uv.GetX() * uv.GetX() + uv.GetY() * uv.GetY())); + } + + // Generates filter weights for the 3x3 neighborhood of a pixel. Since jitter positions are the + // same for every pixel we can calculate this once here and upload to the SRG. + // Jitter weights are based on a window function centered at the pixel center (we use Blackman-Harris). + // As the jitter position moves around, some neighborhood locations decrease in weight, and others + // increase in weight based on their distance from the center of the pixel. + void TaaPass::GenerateFilterWeights(AZ::Vector2 jitterOffset) + { + static const AZStd::array pixelOffsets = + { + // Center + Vector2(0.0f, 0.0f), + // Cross + Vector2( 1.0f, 0.0f), + Vector2( 0.0f, 1.0f), + Vector2(-1.0f, 0.0f), + Vector2( 0.0f, -1.0f), + // Diagonals + Vector2( 1.0f, 1.0f), + Vector2( 1.0f, -1.0f), + Vector2(-1.0f, 1.0f), + Vector2(-1.0f, -1.0f), + }; + + float sum = 0.0f; + for (uint32_t i = 0; i < 9; ++i) + { + m_filterWeights[i] = BlackmanHarris(pixelOffsets[i] + jitterOffset); + sum += m_filterWeights[i]; + } + + // Normalize the weight so the sum of all weights is 1.0. + float normalization = 1.0f / sum; + for (uint32_t i = 0; i < 9; ++i) + { + m_filterWeights[i] *= normalization; + } + } + +} // namespace AZ::Render diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.h new file mode 100644 index 0000000000..6133720691 --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.h @@ -0,0 +1,105 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ +#pragma once + +#include +#include + +namespace AZ::Render +{ + //! Custom data for the Taa Pass. + struct TaaPassData + : public RPI::ComputePassData + { + AZ_RTTI(TaaPassData, "{BCDF5C7D-7A78-4C69-A460-FA6899C3B960}", ComputePassData); + AZ_CLASS_ALLOCATOR(TaaPassData, SystemAllocator, 0); + + TaaPassData() = default; + virtual ~TaaPassData() = default; + + static void Reflect(ReflectContext* context) + { + if (auto* serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Version(1) + ->Field("NumJitterPositions", &TaaPassData::m_numJitterPositions) + ; + } + } + + uint32_t m_numJitterPositions = 8; + }; + + class TaaPass : public RPI::ComputePass + { + using Base = RPI::ComputePass; + AZ_RPI_PASS(TaaPass); + + public: + AZ_RTTI(AZ::Render::TaaPass, "{AB3BD4EA-33D7-477F-82B4-21DDFB517499}", Base); + AZ_CLASS_ALLOCATOR(TaaPass, SystemAllocator, 0); + virtual ~TaaPass() = default; + + /// Creates a TaaPass + static RPI::Ptr Create(const RPI::PassDescriptor& descriptor); + + private: + + TaaPass(const RPI::PassDescriptor& descriptor); + + // Scope producer functions... + void CompileResources(const RHI::FrameGraphCompileContext& context) override; + + // Pass behavior overrides... + void FrameBeginInternal(FramePrepareParams params) override; + void ResetInternal() override; + void BuildAttachmentsInternal() override; + + void UpdateAttachmentImage(RPI::Ptr& attachment); + + void SetupSubPixelOffsets(uint32_t haltonX, uint32_t haltonY, uint32_t length); + void GenerateFilterWeights(AZ::Vector2 jitterOffset); + + RHI::ShaderInputNameIndex m_outputIndex = "m_output"; + RHI::ShaderInputNameIndex m_lastFrameAccumulationIndex = "m_lastFrameAccumulation"; + RHI::ShaderInputNameIndex m_constantDataIndex = "m_constantData"; + + Data::Instance m_accumulationAttachments[2]; + + RPI::PassAttachmentBinding* m_inputColorBinding = nullptr; + RPI::PassAttachmentBinding* m_lastFrameAccumulationBinding = nullptr; + RPI::PassAttachmentBinding* m_outputColorBinding = nullptr; + + struct Offset + { + Offset() = default; + + // Constructor for implicit conversion from array output by HaltonSequence. + Offset(AZStd::array offsets) + : m_xOffset(offsets[0]) + , m_yOffset(offsets[1]) + {}; + + float m_xOffset = 0.0f; + float m_yOffset = 0.0f; + }; + + AZStd::array m_filterWeights = { 0.0f }; + + AZStd::vector m_subPixelOffsets; + uint32_t m_offsetIndex = 0; + + uint8_t m_accumulationOuptutIndex = 0; + + }; +} // namespace AZ::Render diff --git a/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake b/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake index a108fc82f5..a759de77fa 100644 --- a/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake +++ b/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake @@ -252,6 +252,8 @@ set(FILES Source/PostProcessing/SsaoPasses.h Source/PostProcessing/SubsurfaceScatteringPass.cpp Source/PostProcessing/SubsurfaceScatteringPass.h + Source/PostProcessing/TaaPass.h + Source/PostProcessing/TaaPass.cpp Source/RayTracing/RayTracingFeatureProcessor.h Source/RayTracing/RayTracingFeatureProcessor.cpp Source/RayTracing/RayTracingAccelerationStructurePass.cpp diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/FrameGraphAttachmentInterface.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/FrameGraphAttachmentInterface.h index c3194efbb6..af29079a97 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/FrameGraphAttachmentInterface.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/FrameGraphAttachmentInterface.h @@ -89,6 +89,12 @@ namespace AZ return m_attachmentDatabase.IsAttachmentValid(attachmentId); } + //! Returns the FrameAttachment for a given AttachmentId, or nullptr if not found. + const FrameAttachment* FindAttachment(const AttachmentId& attachmentId) const + { + return m_attachmentDatabase.FindAttachment(attachmentId); + } + //! Resolves an attachment id to a buffer descriptor. This is useful when accessing buffer information for //! an attachment that was declared in a different scope. //! \param attachmentId The attachment id used to lookup the descriptors. diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h index 1cba71ae7e..3d0a8cd3a8 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h @@ -184,8 +184,8 @@ namespace AZ //! Collect all different view tags from this pass virtual void GetPipelineViewTags(SortedPipelineViewTags& outTags) const; - //! Adds this pass' DrawListTags to the outDrawListMask. - virtual void GetViewDrawListInfo(RHI::DrawListMask& outDrawListMask, PassesByDrawList& outPassesByDrawList, const PipelineViewTag& viewTag) const; + //! Adds this pass' DrawListTags to the outDrawListMask. + virtual void GetViewDrawListInfo(RHI::DrawListMask& outDrawListMask, PassesByDrawList& outPassesByDrawList, const PipelineViewTag& viewTag) const; //! Check if the pass has a DrawListTag. Pass' DrawListTag can be used to filter draw items. virtual RHI::DrawListTag GetDrawListTag() const; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassAttachment.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassAttachment.h index 5509398f55..fd2a49a941 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassAttachment.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassAttachment.h @@ -52,7 +52,8 @@ namespace AZ const RHI::TransientBufferDescriptor GetTransientBufferDescriptor() const; //! Updates the size and format of this attachment using the sources below if specified - void Update(); + //! @param updateImportedAttachments - Imported attchments will only update if this is true. + void Update(bool updateImportedAttachments = false); //! Sets all formats to nearest device supported formats and warns if changes where made void ValidateDeviceFormats(const AZStd::vector& formatFallbacks, RHI::FormatCapabilities capabilities = RHI::FormatCapabilities::None); diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h index e611ecf0d6..fabec8d896 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h @@ -88,6 +88,9 @@ namespace AZ //! Sets the viewToClip matrix and recalculates the other matrices void SetViewToClipMatrix(const AZ::Matrix4x4& viewToClip); + //! Sets a pixel offset on the view, usually used for jittering the camera for anti-aliasing techniques. + void SetClipSpaceOffset(float xOffset, float yOffset); + const AZ::Matrix4x4& GetWorldToViewMatrix() const; //! Use GetViewToWorldMatrix().GetTranslation() to get the camera's position. const AZ::Matrix4x4& GetViewToWorldMatrix() const; @@ -173,7 +176,6 @@ namespace AZ Matrix4x4 m_worldToViewMatrix; Matrix4x4 m_viewToWorldMatrix; Matrix4x4 m_viewToClipMatrix; - Matrix4x4 m_clipToViewMatrix; Matrix4x4 m_clipToWorldMatrix; // View's position in world space @@ -188,17 +190,15 @@ namespace AZ // Cached matrix to transform from world space to clip space Matrix4x4 m_worldToClipMatrix; - Matrix4x4 m_worldToClipPrevMatrix; + Matrix4x4 m_worldToViewPrevMatrix; + Matrix4x4 m_viewToClipPrevMatrix; + + // Clip space offset for camera jitter with taa + Vector2 m_clipSpaceOffset = Vector2(0.0f, 0.0f); // Flags whether view matrices are dirty which requires rebuild srg bool m_needBuildSrg = true; - // Following two bools form a delay circuit to update history of next frame - // if vp matrix is changed during current frame, this is required because - // view class doesn't contain subroutines called at the end of each frame - bool m_worldToClipMatrixChanged = true; - bool m_worldToClipPrevMatrixNeedsUpdate = false; - MatrixChangedEvent m_onWorldToClipMatrixChange; MatrixChangedEvent m_onWorldToViewMatrixChange; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp index 8d613eb2bb..1e230a7fc0 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp @@ -914,23 +914,40 @@ namespace AZ { // make sure to only import the resource one time RHI::AttachmentId attachmentId = attachment->GetAttachmentId(); - if (!attachmentDatabase.IsAttachmentValid(attachmentId)) + const RHI::FrameAttachment* currentAttachment = attachmentDatabase.FindAttachment(attachmentId); + + if (azrtti_istypeof(attachment->m_importedResource.get())) { - if (azrtti_istypeof(attachment->m_importedResource.get())) + Image* image = static_cast(attachment->m_importedResource.get()); + if (currentAttachment == nullptr) { - Image* image = static_cast(attachment->m_importedResource.get()); attachmentDatabase.ImportImage(attachmentId, image->GetRHIImage()); } - else if (azrtti_istypeof(attachment->m_importedResource.get())) + else + { + AZ_Assert(currentAttachment->GetResource() == image->GetRHIImage(), + "Importing image attachment named \"%s\" but a different attachment with the " + "same name already exists in the database.\n", attachmentId.GetCStr()); + } + } + else if (azrtti_istypeof(attachment->m_importedResource.get())) + { + Buffer* buffer = static_cast(attachment->m_importedResource.get()); + if (currentAttachment == nullptr) { - Buffer* buffer = static_cast(attachment->m_importedResource.get()); attachmentDatabase.ImportBuffer(attachmentId, buffer->GetRHIBuffer()); } else { - AZ_RPI_PASS_ERROR(false, "Can't import unknown resource type"); + AZ_Assert(currentAttachment->GetResource() == buffer->GetRHIBuffer(), + "Importing buffer attachment named \"%s\" but a different attachment with the " + "same name already exists in the database.\n", attachmentId.GetCStr()); } } + else + { + AZ_RPI_PASS_ERROR(false, "Can't import unknown resource type"); + } } } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassAttachment.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassAttachment.cpp index a5082c5ee6..3bd26a5906 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassAttachment.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassAttachment.cpp @@ -114,9 +114,9 @@ namespace AZ return RHI::TransientBufferDescriptor(GetAttachmentId(), m_descriptor.m_buffer); } - void PassAttachment::Update() + void PassAttachment::Update(bool updateImportedAttachments) { - if (m_descriptor.m_type == RHI::AttachmentType::Image && m_lifetime == RHI::AttachmentLifetimeType::Transient) + if (m_descriptor.m_type == RHI::AttachmentType::Image && (m_lifetime == RHI::AttachmentLifetimeType::Transient || updateImportedAttachments == true)) { if (m_settingFlags.m_getFormatFromPipeline && m_renderPipelineSource) { diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp index bd0e15fb2e..24dfcb7097 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp @@ -127,7 +127,6 @@ namespace AZ m_worldToViewMatrix = worldToView; m_worldToClipMatrix = m_viewToClipMatrix * m_worldToViewMatrix; - m_worldToClipMatrixChanged = true; m_onWorldToViewMatrixChange.Signal(m_worldToViewMatrix); m_onWorldToClipMatrixChange.Signal(m_worldToClipMatrix); @@ -166,8 +165,6 @@ namespace AZ m_worldToViewMatrix = m_viewToWorldMatrix.GetInverseFast(); m_worldToClipMatrix = m_viewToClipMatrix * m_worldToViewMatrix; - m_clipToWorldMatrix = m_viewToWorldMatrix * m_clipToViewMatrix; - m_worldToClipMatrixChanged = true; m_onWorldToViewMatrixChange.Signal(m_worldToViewMatrix); m_onWorldToClipMatrixChange.Signal(m_worldToClipMatrix); @@ -178,12 +175,8 @@ namespace AZ void View::SetViewToClipMatrix(const AZ::Matrix4x4& viewToClip) { m_viewToClipMatrix = viewToClip; - m_clipToViewMatrix = viewToClip.GetInverseFull(); m_worldToClipMatrix = m_viewToClipMatrix * m_worldToViewMatrix; - m_worldToClipMatrixChanged = true; - - m_clipToWorldMatrix = m_viewToWorldMatrix * m_clipToViewMatrix; // Update z depth constant simultaneously // zNear -> n, zFar -> f @@ -210,6 +203,12 @@ namespace AZ InvalidateSrg(); } + + void View::SetClipSpaceOffset(float xOffset, float yOffset) + { + m_clipSpaceOffset.Set(xOffset, yOffset); + InvalidateSrg(); + } const AZ::Matrix4x4& View::GetWorldToViewMatrix() const { @@ -368,36 +367,56 @@ namespace AZ void View::UpdateSrg() { - if (m_worldToClipPrevMatrixNeedsUpdate) + if (m_needBuildSrg) { - m_shaderResourceGroup->SetConstant(m_worldToClipPrevMatrixConstantIndex, m_worldToClipPrevMatrix); - m_worldToClipPrevMatrixNeedsUpdate = false; - } + if (m_clipSpaceOffset.IsZero()) + { + Matrix4x4 worldToClipPrevMatrix = m_viewToClipPrevMatrix * m_worldToViewPrevMatrix; + m_shaderResourceGroup->SetConstant(m_worldToClipPrevMatrixConstantIndex, worldToClipPrevMatrix); + m_shaderResourceGroup->SetConstant(m_viewProjectionMatrixConstantIndex, m_worldToClipMatrix); + m_shaderResourceGroup->SetConstant(m_projectionMatrixConstantIndex, m_viewToClipMatrix); + m_shaderResourceGroup->SetConstant(m_clipToWorldMatrixConstantIndex, m_clipToWorldMatrix); + m_shaderResourceGroup->SetConstant(m_projectionMatrixInverseConstantIndex, m_viewToClipMatrix.GetInverseFull()); + } + else + { + // Offset the current and previous frame clip matricies + Matrix4x4 offsetViewToClipMatrix = m_viewToClipMatrix; + offsetViewToClipMatrix.SetElement(0, 2, m_clipSpaceOffset.GetX()); + offsetViewToClipMatrix.SetElement(1, 2, m_clipSpaceOffset.GetY()); + + Matrix4x4 offsetViewToClipPrevMatrix = m_viewToClipPrevMatrix; + offsetViewToClipPrevMatrix.SetElement(0, 2, m_clipSpaceOffset.GetX()); + offsetViewToClipPrevMatrix.SetElement(1, 2, m_clipSpaceOffset.GetY()); + + // Build other matricies dependent on the view to clip matricies + Matrix4x4 offsetWorldToClipMatrix = offsetViewToClipMatrix * m_worldToViewMatrix; + Matrix4x4 offsetWorldToClipPrevMatrix = offsetViewToClipPrevMatrix * m_worldToViewPrevMatrix; + + Matrix4x4 offsetClipToViewMatrix = offsetViewToClipMatrix.GetInverseFull(); + Matrix4x4 offsetClipToWorldMatrix = m_viewToWorldMatrix * offsetClipToViewMatrix; + + m_shaderResourceGroup->SetConstant(m_worldToClipPrevMatrixConstantIndex, offsetWorldToClipPrevMatrix); + m_shaderResourceGroup->SetConstant(m_viewProjectionMatrixConstantIndex, offsetWorldToClipMatrix); + m_shaderResourceGroup->SetConstant(m_projectionMatrixConstantIndex, offsetViewToClipMatrix); + m_shaderResourceGroup->SetConstant(m_clipToWorldMatrixConstantIndex, offsetClipToWorldMatrix); + m_shaderResourceGroup->SetConstant(m_projectionMatrixInverseConstantIndex, offsetViewToClipMatrix.GetInverseFull()); + } - if (m_worldToClipMatrixChanged) - { - m_worldToClipPrevMatrix = m_worldToClipMatrix; - m_worldToClipPrevMatrixNeedsUpdate = true; - m_worldToClipMatrixChanged = false; - } + m_shaderResourceGroup->SetConstant(m_worldPositionConstantIndex, m_position); + m_shaderResourceGroup->SetConstant(m_viewMatrixConstantIndex, m_worldToViewMatrix); + m_shaderResourceGroup->SetConstant(m_viewMatrixInverseConstantIndex, m_worldToViewMatrix.GetInverseFull()); + m_shaderResourceGroup->SetConstant(m_zConstantsConstantIndex, m_nearZ_farZ_farZTimesNearZ_farZMinusNearZ); + m_shaderResourceGroup->SetConstant(m_unprojectionConstantsIndex, m_unprojectionConstants); - if (!m_needBuildSrg) - { - return; + m_shaderResourceGroup->Compile(); + m_needBuildSrg = false; } - m_shaderResourceGroup->SetConstant(m_worldPositionConstantIndex, m_position); - m_shaderResourceGroup->SetConstant(m_viewProjectionMatrixConstantIndex, m_worldToClipMatrix); - m_shaderResourceGroup->SetConstant(m_viewMatrixConstantIndex, m_worldToViewMatrix); - m_shaderResourceGroup->SetConstant(m_viewMatrixInverseConstantIndex, m_worldToViewMatrix.GetInverseFull()); - m_shaderResourceGroup->SetConstant(m_projectionMatrixConstantIndex, m_viewToClipMatrix); - m_shaderResourceGroup->SetConstant(m_projectionMatrixInverseConstantIndex, m_viewToClipMatrix.GetInverseFull()); - m_shaderResourceGroup->SetConstant(m_zConstantsConstantIndex, m_nearZ_farZ_farZTimesNearZ_farZMinusNearZ); - m_shaderResourceGroup->SetConstant(m_clipToWorldMatrixConstantIndex, m_clipToWorldMatrix); - m_shaderResourceGroup->SetConstant(m_unprojectionConstantsIndex, m_unprojectionConstants); - - m_shaderResourceGroup->Compile(); - m_needBuildSrg = false; + m_viewToClipPrevMatrix = m_viewToClipMatrix; + m_worldToViewPrevMatrix = m_worldToViewMatrix; + + m_clipSpaceOffset.Set(0); } void View::BeginCulling() From bf29b27937f4f1ff0828a6b49859e7e0570b685e Mon Sep 17 00:00:00 2001 From: amzn-hdoke <61443753+hdoke@users.noreply.github.com> Date: Fri, 4 Jun 2021 20:48:35 -0700 Subject: [PATCH 09/15] Add AWSAttribution feature (#1164) * LYN-3601: Provide skeleton classes for AWS Attribution (#31) Provide skeleton classes for AWS Attribution, along with some basic unit tests * Add AWS Attribution UI and settings (#56) * Adding AWS Attributions UX and corresponding editor preference s setting * Fix serialized field description * Fixed update frequency to be a day * Handling editor startup with default values for AWSAttribution * Add missing header and remove AWSCoreSystemComponentMock fron test * Generate and post AWSAttribution metric (#69) * Adding AWS Attribution Api service job * Adding support for config endpoint override * Update Api endpoint formatting, fix default region * Remove extra header * Fixes for link issues * Fix Unittest namespace * Instantiating AWSAttributionSystemComponent in AWS.Editor module * Update AttributionMetric with engine version and AWS enabled gems (#77) * Update AttributionMetric with engine version and AWS enabled gems * Fix warnings * Undoing accidental change * Saving level PrefabLevel_OpensLevelWithEntities * Remove overriding editorprefrences.setreg * Revert "Saving level PrefabLevel_OpensLevelWithEntities" This reverts commit 529af70c55ece70fc6bc29ceb83bef60413713a3. * Move AWS preferences to its own temp settings file * Undo accidental file add * Add missing string params in warning messages Co-authored-by: Pip Potter <61438964+lmbr-pip@users.noreply.github.com> --- .../Editor/EditorPreferencesDialog.cpp | 2 + .../Editor/EditorPreferencesPageAWS.cpp | 151 +++++++ .../Sandbox/Editor/EditorPreferencesPageAWS.h | 60 +++ Code/Sandbox/Editor/MainWindow.qrc | 1 + Code/Sandbox/Editor/PreferencesStdPages.cpp | 8 + Code/Sandbox/Editor/editor_lib_files.cmake | 2 + .../Editor/res/AWS_preferences_icon.svg | 3 + Gems/AWSCore/Code/CMakeLists.txt | 4 +- .../Include/Private/AWSCoreEditorModule.h | 2 +- .../Attribution/AWSAttributionServiceApi.h | 71 +++ .../Attribution/AWSCoreAttributionConstant.h | 25 ++ .../Attribution/AWSCoreAttributionManager.h | 53 +++ .../Attribution/AWSCoreAttributionMetric.h | 62 +++ .../AWSCoreAttributionSystemComponent.h | 50 +++ .../Public/Framework/ServiceClientJobConfig.h | 6 + .../Code/Source/AWSCoreEditorModule.cpp | 5 +- .../Attribution/AWSAttributionServiceApi.cpp | 45 ++ .../Attribution/AWSCoreAttributionManager.cpp | 275 ++++++++++++ .../Attribution/AWSCoreAttributionMetric.cpp | 106 +++++ .../AWSCoreAttributionSystemComponent.cpp | 81 ++++ .../AWSAttributionServiceApiTest.cpp | 85 ++++ .../AWSCoreAttributionManagerTest.cpp | 414 ++++++++++++++++++ .../AWSCoreAttributionMetricTest.cpp | 50 +++ .../AWSCoreAttributionSystemComponentTest.cpp | 132 ++++++ .../Code/Tests/TestFramework/AWSCoreFixture.h | 31 +- Gems/AWSCore/Code/awscore_editor_files.cmake | 9 + .../Code/awscore_editor_tests_files.cmake | 4 + 27 files changed, 1732 insertions(+), 5 deletions(-) create mode 100644 Code/Sandbox/Editor/EditorPreferencesPageAWS.cpp create mode 100644 Code/Sandbox/Editor/EditorPreferencesPageAWS.h create mode 100644 Code/Sandbox/Editor/res/AWS_preferences_icon.svg create mode 100644 Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSAttributionServiceApi.h create mode 100644 Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionConstant.h create mode 100644 Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionManager.h create mode 100644 Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionMetric.h create mode 100644 Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionSystemComponent.h create mode 100644 Gems/AWSCore/Code/Source/Editor/Attribution/AWSAttributionServiceApi.cpp create mode 100644 Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp create mode 100644 Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionMetric.cpp create mode 100644 Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionSystemComponent.cpp create mode 100644 Gems/AWSCore/Code/Tests/Editor/Attribution/AWSAttributionServiceApiTest.cpp create mode 100644 Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionManagerTest.cpp create mode 100644 Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionMetricTest.cpp create mode 100644 Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionSystemComponentTest.cpp diff --git a/Code/Sandbox/Editor/EditorPreferencesDialog.cpp b/Code/Sandbox/Editor/EditorPreferencesDialog.cpp index e5bcfd6bad..679c73e7df 100644 --- a/Code/Sandbox/Editor/EditorPreferencesDialog.cpp +++ b/Code/Sandbox/Editor/EditorPreferencesDialog.cpp @@ -35,6 +35,7 @@ #include "EditorPreferencesPageViewportMovement.h" #include "EditorPreferencesPageViewportDebug.h" #include "EditorPreferencesPageExperimentalLighting.h" +#include "EditorPreferencesPageAWS.h" #include "LyViewPaneNames.h" AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING @@ -72,6 +73,7 @@ EditorPreferencesDialog::EditorPreferencesDialog(QWidget* pParent) CEditorPreferencesPage_ViewportMovement::Reflect(*serializeContext); CEditorPreferencesPage_ViewportDebug::Reflect(*serializeContext); CEditorPreferencesPage_ExperimentalLighting::Reflect(*serializeContext); + CEditorPreferencesPage_AWS::Reflect(*serializeContext); } } diff --git a/Code/Sandbox/Editor/EditorPreferencesPageAWS.cpp b/Code/Sandbox/Editor/EditorPreferencesPageAWS.cpp new file mode 100644 index 0000000000..edaf813cd8 --- /dev/null +++ b/Code/Sandbox/Editor/EditorPreferencesPageAWS.cpp @@ -0,0 +1,151 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ +#include "EditorDefs.h" + +#include "EditorPreferencesPageAWS.h" + +// AzCore +#include +#include +#include + +void CEditorPreferencesPage_AWS::Reflect(AZ::SerializeContext& serialize) +{ + serialize.Class() + ->Version(1) + ->Field("AWSAttributionEnabled", &UsageOptions::m_awsAttributionEnabled); + + serialize.Class() + ->Version(1) + ->Field("UsageOptions", &CEditorPreferencesPage_AWS::m_usageOptions); + + AZ::EditContext* editContext = serialize.GetEditContext(); + if (editContext) + { + editContext->Class("Options", "") + ->DataElement(AZ::Edit::UIHandlers::CheckBox, &UsageOptions::m_awsAttributionEnabled, "Send Metrics usage to AWS", + "Reports Gem usage to AWS on Editor launch"); + + editContext->Class("AWS Preferences", "AWS Preferences") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::Visibility, AZ_CRC("PropertyVisibility_ShowChildrenOnly", 0xef428f20)) + ->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_AWS::m_usageOptions, "AWS Usage Data", "AWS Usage Options"); + } +} + + +CEditorPreferencesPage_AWS::CEditorPreferencesPage_AWS() +{ + m_settingsRegistry = AZStd::make_unique(); + InitializeSettings(); + + // TODO Update with AWS svg. + m_icon = QIcon(":/res/AWS_preferences_icon.svg"); +} + +CEditorPreferencesPage_AWS::~CEditorPreferencesPage_AWS() +{ + m_settingsRegistry.reset(); +} + +const char* CEditorPreferencesPage_AWS::GetTitle() +{ + return "AWS"; +} + +QIcon& CEditorPreferencesPage_AWS::GetIcon() +{ + return m_icon; +} + +void CEditorPreferencesPage_AWS::OnApply() +{ + m_settingsRegistry->Set(AWSAttributionEnabledKey, m_usageOptions.m_awsAttributionEnabled); + SaveSettingsRegistryFile(); +} + +const CEditorPreferencesPage_AWS::UsageOptions& CEditorPreferencesPage_AWS::GetUsageOptions() +{ + return m_usageOptions; +} + +void CEditorPreferencesPage_AWS::SaveSettingsRegistryFile() +{ + AZ::Job* job = AZ::CreateJobFunction( + [this]() + { + AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); + AZ_Assert(fileIO, "File IO is not initialized."); + + // Resolve path to editor_aws_preferences.setreg + AZStd::string editorPreferencesFilePath = + AZStd::string::format("@user@/%s/%s", AZ::SettingsRegistryInterface::RegistryFolder, EditorAWSPreferencesFileName); + AZStd::array resolvedPath{}; + fileIO->ResolvePath(editorPreferencesFilePath.c_str(), resolvedPath.data(), resolvedPath.size()); + + AZ::SettingsRegistryMergeUtils::DumperSettings dumperSettings; + dumperSettings.m_prettifyOutput = true; + dumperSettings.m_jsonPointerPrefix = AWSAttributionSettingsPrefixKey; + + AZStd::string stringBuffer; + AZ::IO::ByteContainerStream stringStream(&stringBuffer); + if (!AZ::SettingsRegistryMergeUtils::DumpSettingsRegistryToStream( + *m_settingsRegistry, AWSAttributionSettingsPrefixKey, stringStream, dumperSettings)) + { + AZ_Warning( + "AWSAttributionManager", false, R"(Unable to save changes to the Editor AWS Preferences registry file at "%s"\n)", + resolvedPath.data()); + return; + } + + bool saved{}; + constexpr auto configurationMode = + AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY; + if (AZ::IO::SystemFile outputFile; outputFile.Open(resolvedPath.data(), configurationMode)) + { + saved = outputFile.Write(stringBuffer.data(), stringBuffer.size()) == stringBuffer.size(); + } + + AZ_Warning( + "AWSAttributionManager", saved, R"(Unable to save Editor AWS Preferences registry file to path "%s"\n)", + editorPreferencesFilePath.c_str()); + }, + true); + job->Start(); +} + +void CEditorPreferencesPage_AWS::InitializeSettings() +{ + AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); + AZ_Assert(fileIO, "File IO is not initialized."); + + // Resolve path to editor_aws_preferences.setreg + AZStd::string editorAWSPreferencesFilePath = + AZStd::string::format("@user@/%s/%s", AZ::SettingsRegistryInterface::RegistryFolder, EditorAWSPreferencesFileName); + AZStd::array resolvedPathAWSPreference{}; + if (!fileIO->ResolvePath(editorAWSPreferencesFilePath.c_str(), resolvedPathAWSPreference.data(), resolvedPathAWSPreference.size())) + { + AZ_Warning("AWSAttributionManager", false, "Error resolving path %s", resolvedPathAWSPreference.data()); + return; + } + + if (fileIO->Exists(resolvedPathAWSPreference.data())) + { + m_settingsRegistry->MergeSettingsFile(resolvedPathAWSPreference.data(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ""); + } + + if (!m_settingsRegistry->Get(m_usageOptions.m_awsAttributionEnabled, AWSAttributionEnabledKey)) + { + // If key is missing default to on. + m_usageOptions.m_awsAttributionEnabled = true; + } +} diff --git a/Code/Sandbox/Editor/EditorPreferencesPageAWS.h b/Code/Sandbox/Editor/EditorPreferencesPageAWS.h new file mode 100644 index 0000000000..b0dc7ee740 --- /dev/null +++ b/Code/Sandbox/Editor/EditorPreferencesPageAWS.h @@ -0,0 +1,60 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ +#pragma once + +#include "Include/IPreferencesPage.h" +#include +#include +#include +#include + +class CEditorPreferencesPage_AWS + : public IPreferencesPage +{ +public: + AZ_RTTI(CEditorPreferencesPage_AWS, "{51FB9557-ABA3-4FD7-803A-1784F5B06F5F}", IPreferencesPage) + + static void Reflect(AZ::SerializeContext& serialize); + + CEditorPreferencesPage_AWS(); + virtual ~CEditorPreferencesPage_AWS(); + + // IPreferencesPage interface methods. + virtual const char* GetCategory() override { return "AWS"; } + virtual const char* GetTitle() override; + virtual QIcon& GetIcon() override; + virtual void OnApply() override; + virtual void OnCancel() override {} + virtual bool OnQueryCancel() override { return true; } + +protected: + struct UsageOptions + { + AZ_TYPE_INFO(UsageOptions, "{2B7D9B19-D13B-4E54-B724-B2FD8D0828B3}") + + bool m_awsAttributionEnabled; + }; + + const UsageOptions& GetUsageOptions(); + +private: + void InitializeSettings(); + void SaveSettingsRegistryFile(); + UsageOptions m_usageOptions; + QIcon m_icon; + AZStd::unique_ptr m_settingsRegistry; + + static constexpr char AWSAttributionEnabledKey[] = "/Amazon/AWS/Preferences/AWSAttributionEnabled"; + static constexpr char EditorPreferencesFileName[] = "editorpreferences.setreg"; + static constexpr char EditorAWSPreferencesFileName[] = "editor_aws_preferences.setreg"; + static constexpr char AWSAttributionSettingsPrefixKey[] = "/Amazon/AWS/Preferences"; +}; diff --git a/Code/Sandbox/Editor/MainWindow.qrc b/Code/Sandbox/Editor/MainWindow.qrc index 476159fbfd..fd207ebe13 100644 --- a/Code/Sandbox/Editor/MainWindow.qrc +++ b/Code/Sandbox/Editor/MainWindow.qrc @@ -143,6 +143,7 @@ res/Camera.svg res/Debug.svg res/Experimental.svg + res/AWS_preferences_icon.svg res/Files.svg res/Gizmos.svg res/Global.svg diff --git a/Code/Sandbox/Editor/PreferencesStdPages.cpp b/Code/Sandbox/Editor/PreferencesStdPages.cpp index 032b01e353..3a66d6e3f4 100644 --- a/Code/Sandbox/Editor/PreferencesStdPages.cpp +++ b/Code/Sandbox/Editor/PreferencesStdPages.cpp @@ -15,6 +15,8 @@ #include "PreferencesStdPages.h" +#include + // Editor #include "EditorPreferencesPageGeneral.h" #include "EditorPreferencesPageFiles.h" @@ -23,6 +25,7 @@ #include "EditorPreferencesPageViewportMovement.h" #include "EditorPreferencesPageViewportDebug.h" #include "EditorPreferencesPageExperimentalLighting.h" +#include "EditorPreferencesPageAWS.h" ////////////////////////////////////////////////////////////////////////// @@ -42,6 +45,11 @@ CStdPreferencesClassDesc::CStdPreferencesClassDesc() }; m_pageCreators.push_back([]() { return new CEditorPreferencesPage_ExperimentalLighting(); }); + + if (AzToolsFramework::IsComponentWithServiceRegistered(AZ_CRC_CE("AWSCoreEditorService"))) + { + m_pageCreators.push_back([]() { return new CEditorPreferencesPage_AWS(); }); + } } HRESULT CStdPreferencesClassDesc::QueryInterface(const IID& riid, void** ppvObj) diff --git a/Code/Sandbox/Editor/editor_lib_files.cmake b/Code/Sandbox/Editor/editor_lib_files.cmake index e1cf18df55..ebd7f89cfb 100644 --- a/Code/Sandbox/Editor/editor_lib_files.cmake +++ b/Code/Sandbox/Editor/editor_lib_files.cmake @@ -586,6 +586,8 @@ set(FILES EditorPreferencesPageViewportDebug.cpp EditorPreferencesPageExperimentalLighting.h EditorPreferencesPageExperimentalLighting.cpp + EditorPreferencesPageAWS.h + EditorPreferencesPageAWS.cpp EditorPreferencesDialog.h EditorPreferencesDialog.cpp EditorPreferencesDialog.ui diff --git a/Code/Sandbox/Editor/res/AWS_preferences_icon.svg b/Code/Sandbox/Editor/res/AWS_preferences_icon.svg new file mode 100644 index 0000000000..e2a86cf162 --- /dev/null +++ b/Code/Sandbox/Editor/res/AWS_preferences_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/Gems/AWSCore/Code/CMakeLists.txt b/Gems/AWSCore/Code/CMakeLists.txt index 7edb22124f..d6cd57355f 100644 --- a/Gems/AWSCore/Code/CMakeLists.txt +++ b/Gems/AWSCore/Code/CMakeLists.txt @@ -64,11 +64,13 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) Include/Public BUILD_DEPENDENCIES PRIVATE + AZ::AzQtComponents 3rdParty::Qt::Core 3rdParty::Qt::Widgets - AZ::AzQtComponents + Gem::AWSCore.Static PUBLIC AZ::AzToolsFramework + 3rdParty::AWSNativeSDK::AWSCore ) ly_add_target( diff --git a/Gems/AWSCore/Code/Include/Private/AWSCoreEditorModule.h b/Gems/AWSCore/Code/Include/Private/AWSCoreEditorModule.h index 45a2c1f9f7..144976f355 100644 --- a/Gems/AWSCore/Code/Include/Private/AWSCoreEditorModule.h +++ b/Gems/AWSCore/Code/Include/Private/AWSCoreEditorModule.h @@ -16,7 +16,7 @@ namespace AWSCore { class AWSCoreEditorModule - :public AZ::Module + : public AZ::Module { public: AZ_RTTI(AWSCoreEditorModule, "{C1C9B898-848B-4C2F-A7AA-69642D12BCB5}", AZ::Module); diff --git a/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSAttributionServiceApi.h b/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSAttributionServiceApi.h new file mode 100644 index 0000000000..d14e51589c --- /dev/null +++ b/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSAttributionServiceApi.h @@ -0,0 +1,71 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +#include +#include + +namespace AWSCore +{ + namespace ServiceAPI + { + //! Struct for storing the success response. + struct AWSAtrributionSuccessResponse + { + //! Identify the expected property type and provide a location where the property value can be stored. + //! @param key Name of the property. + //! @param reader JSON reader to read the property. + bool OnJsonKey(const char* key, AWSCore::JsonReader& reader); + + AZStd::string result; //!< Processing result for the input record. + }; + + // Service RequestJobs + AWS_FEATURE_GEM_SERVICE(AWSAttribution); + + //! POST request to send attribution metric to the backend. + //! The path for this service API is "/prod/metrics". + class AWSAttributionRequest + : public AWSCore::ServiceRequest + { + public: + SERVICE_REQUEST(AWSAttribution, HttpMethod::HTTP_POST, "/metrics"); + + bool UseAWSCredentials() + { + return false; + } + + //! Request body for the service API request. + struct Parameters + { + //! Build the service API request. + //! @request Builder for generating the request. + //! @return Whether the request is built successfully. + bool BuildRequest(AWSCore::RequestBuilder& request); + + //! Write to the service API request body. + //! @param writer JSON writer for the serialization. + //! @return Whether the serialization is successful. + bool WriteJson(AWSCore::JsonWriter& writer) const; + + AttributionMetric metric; + }; + + AWSAtrributionSuccessResponse result; + Parameters parameters; //! Request parameter. + }; + + using AWSAttributionRequestJob = AWSCore::ServiceRequestJob; + } // ServiceAPI +} // AWSMetrics diff --git a/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionConstant.h b/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionConstant.h new file mode 100644 index 0000000000..503abfb9cf --- /dev/null +++ b/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionConstant.h @@ -0,0 +1,25 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#pragma once + +namespace AWSCore +{ + //! Default metrics attribute keys + static constexpr char AwsAttributionAttributeKeyVersion[] = "version"; + static constexpr char AwsAttributionAttributeKeyO3DEVersion[] = "o3de_version"; + static constexpr char AwsAttributionAttributeKeyPlatform[] = "platform"; + static constexpr char AwsAttributionAttributeKeyPlatformVersion[] = "platform_version"; + static constexpr char AwsAttributionAttributeKeyActiveAWSGems[] = "aws_gems"; + static constexpr char AwsAttributionAttributeKeyTimestamp[] = "timestamp"; + +} // namespace AWSCOre diff --git a/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionManager.h b/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionManager.h new file mode 100644 index 0000000000..ad3b8c72c9 --- /dev/null +++ b/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionManager.h @@ -0,0 +1,53 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#pragma once +#include +#include + +#include +#include + +namespace AWSCore +{ + //! Manages operational metrics for AWS gems + class AWSAttributionManager + { + public: + AWSAttributionManager(); + virtual ~AWSAttributionManager(); + + //! Perform initialization + void Init(); + + //! Run metric check + void MetricCheck(); + + protected: + virtual void SubmitMetric(AttributionMetric& metric); + virtual void UpdateMetric(AttributionMetric& metric); + void UpdateLastSend(); + void SetApiEndpointAndRegion(ServiceAPI::AWSAttributionRequestJob::Config* config); + + private: + bool ShouldGenerateMetric() const; + + AZStd::string GetEngineVersion() const; + AZStd::string GetPlatform() const; + void GetActiveAWSGems(AZStd::vector& gemNames); + + void SaveSettingsRegistryFile(); + + AZStd::unique_ptr m_settingsRegistry; + }; + +} // namespace AWSCore diff --git a/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionMetric.h b/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionMetric.h new file mode 100644 index 0000000000..42518b8df5 --- /dev/null +++ b/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionMetric.h @@ -0,0 +1,62 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or + * a third party where indicated. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#pragma once + +#include + +#include +#include +#include +#include + +namespace AWSCore +{ + //! Defines the operational metric sent periodically + class AttributionMetric + { + public: + AZ_TYPE_INFO(MetricsAttribute, "{6483F481-0C18-4171-8B59-A44F2F28EAE5}") + + AttributionMetric(); + AttributionMetric(const AZStd::string& timestamp); + ~AttributionMetric() = default; + + void SetO3DEVersion(const AZStd::string& version); + void SetPlatform(const AZStd::string& platform, const AZStd::string& platformVersion); + void AddActiveGem(const AZStd::string& gemName); + + //! Serialize the metrics object queue to a string. + //! @return Serialized string. + AZStd::string SerializeToJson(); + + //! Serialize the metrics object to JSON for the sending requests. + //! @param writer JSON writer for the serialization. + //! @return Whether the metrics event is serialized successfully. + bool SerializeToJson(AWSCore::JsonWriter& writer) const; + + //! Read from a JSON value to the metrics event. + //! @param metricsObjVal JSON value to read from. + //! @return Whether the metrics event is created successfully. + bool ReadFromJson(rapidjson::Value& metricsObjVal); + + //! Generates a UTC 8601 formatted timestamp + static AZStd::string GenerateTimeStamp(); + private: + AZStd::string m_version; //!< Schema version in use + AZStd::string m_o3deVersion; //!< O3DE editor version in use + AZStd::string m_platform; //!< OS type + AZStd::string m_platformVersion; //!< OS subtype + AZStd::string m_timestamp; //!< Metric generation time + AZStd::vector m_activeAWSGems; //!< Active AWS Gems in project + }; +} // namespace AWSCore diff --git a/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionSystemComponent.h b/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionSystemComponent.h new file mode 100644 index 0000000000..476b7ba842 --- /dev/null +++ b/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionSystemComponent.h @@ -0,0 +1,50 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#pragma once + +#include +#include + +namespace AWSCore +{ + class AWSAttributionManager; + + //! Attribution System Component. Responsible for instantiating and managing AWS Attribution Manager + class AWSAttributionSystemComponent: + public AZ::Component + { + public: + AZ_COMPONENT(AWSAttributionSystemComponent, "{366861EC-8337-4180-A202-4E4DF082A3A8}"); + + AWSAttributionSystemComponent(); + ~AWSAttributionSystemComponent() = default; + + static void Reflect(AZ::ReflectContext* context);\ + + 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 implementation + void Init() override; + void Activate() override; + void Deactivate() override; + //////////////////////////////////////////////////////////////////////// + + private: + AZStd::unique_ptr m_manager; //!< pointer to the attribution manager which handles operational metrics + }; +} // namespace AWSCore diff --git a/Gems/AWSCore/Code/Include/Public/Framework/ServiceClientJobConfig.h b/Gems/AWSCore/Code/Include/Public/Framework/ServiceClientJobConfig.h index 722fc098a0..709e786adc 100644 --- a/Gems/AWSCore/Code/Include/Public/Framework/ServiceClientJobConfig.h +++ b/Gems/AWSCore/Code/Include/Public/Framework/ServiceClientJobConfig.h @@ -113,7 +113,13 @@ namespace AWSCore /// needed. See it's use in ServiceRequestJobConfig. const AZStd::string GetServiceUrl() override { + if (endpointOverride.has_value()) + { + return endpointOverride.value().c_str(); + } + AZStd::string serviceUrl; + if (!ServiceTraitsType::RESTApiIdKeyName && !ServiceTraitsType::RESTApiStageKeyName) { AWSResourceMappingRequestBus::BroadcastResult( diff --git a/Gems/AWSCore/Code/Source/AWSCoreEditorModule.cpp b/Gems/AWSCore/Code/Source/AWSCoreEditorModule.cpp index 69e45bfd68..2f4519c960 100644 --- a/Gems/AWSCore/Code/Source/AWSCoreEditorModule.cpp +++ b/Gems/AWSCore/Code/Source/AWSCoreEditorModule.cpp @@ -11,6 +11,7 @@ #include #include +#include namespace AWSCore { @@ -19,6 +20,7 @@ namespace AWSCore // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here. m_descriptors.insert(m_descriptors.end(), { AWSCoreEditorSystemComponent::CreateDescriptor(), + AWSAttributionSystemComponent::CreateDescriptor() }); } @@ -28,7 +30,8 @@ namespace AWSCore AZ::ComponentTypeList AWSCoreEditorModule::GetRequiredSystemComponents() const { return AZ::ComponentTypeList{ - azrtti_typeid() + azrtti_typeid(), + azrtti_typeid() }; } diff --git a/Gems/AWSCore/Code/Source/Editor/Attribution/AWSAttributionServiceApi.cpp b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSAttributionServiceApi.cpp new file mode 100644 index 0000000000..3c82ec98f9 --- /dev/null +++ b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSAttributionServiceApi.cpp @@ -0,0 +1,45 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include +#include + +namespace AWSCore +{ + namespace ServiceAPI + { + constexpr char AwsAttributionServiceResultResponseKey[] = "statusCode"; + + bool AWSAtrributionSuccessResponse::OnJsonKey(const char* key, AWSCore::JsonReader& reader) + { + if (strcmp(key, AwsAttributionServiceResultResponseKey) == 0) + { + return reader.Accept(result); + } + return reader.Ignore(); + } + + bool AWSAttributionRequest::Parameters::BuildRequest(AWSCore::RequestBuilder& request) + { + bool ok = true; + ok = ok && request.WriteJsonBodyParameter(*this); + return ok; + } + + bool AWSAttributionRequest::Parameters::WriteJson(AWSCore::JsonWriter& writer) const + { + bool ok = true; + ok = ok && metric.SerializeToJson(writer); + return ok; + } + } +} diff --git a/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp new file mode 100644 index 0000000000..e7a6828903 --- /dev/null +++ b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp @@ -0,0 +1,275 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +namespace AWSCore +{ + static constexpr const char* EngineVersionJsonKey = "O3DEVersion"; + + constexpr char EditorAWSPreferencesFileName[] = "editor_aws_preferences.setreg"; + constexpr char AWSAttributionSettingsPrefixKey[] = "/Amazon/AWS/Preferences"; + constexpr char AWSAttributionEnabledKey[] = "/Amazon/AWS/Preferences/AWSAttributionEnabled"; + constexpr char AWSAttributionDelaySecondsKey[] = "/Amazon/AWS/Preferences/AWSAttributionDelaySeconds"; + constexpr char AWSAttributionLastTimeStampKey[] = "/Amazon/AWS/Preferences/AWSAttributionLastTimeStamp"; + constexpr char AWSAttributionApiId[] = "xbzx78kvbk"; + constexpr char AWSAttributionChinaApiId[] = ""; + constexpr char AWSAttributionApiStage[] = "prod"; + + AWSAttributionManager::AWSAttributionManager() + { + m_settingsRegistry = AZStd::make_unique(); + } + + AWSAttributionManager::~AWSAttributionManager() + { + m_settingsRegistry.reset(); + } + + void AWSAttributionManager::Init() + { + } + + void AWSAttributionManager::MetricCheck() + { + if (ShouldGenerateMetric()) + { + // 1. Gather metadata and assemble metric + AttributionMetric metric; + UpdateMetric(metric); + // 2. Identify region and chose attribution endpoint + + // 3. Post metric + SubmitMetric(metric); + } + } + + bool AWSAttributionManager::ShouldGenerateMetric() const + { + AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); + AZ_Assert(fileIO, "File IO is not initialized."); + + // Resolve path to editor_aws_preferences.setreg + AZStd::string editorAWSPreferencesFilePath = + AZStd::string::format("@user@/%s/%s", AZ::SettingsRegistryInterface::RegistryFolder, EditorAWSPreferencesFileName); + AZStd::array resolvedPathAWSPreference{}; + if (!fileIO->ResolvePath(editorAWSPreferencesFilePath.c_str(), resolvedPathAWSPreference.data(), resolvedPathAWSPreference.size())) + { + AZ_Warning("AWSAttributionManager", false, "Error resolving path %s", resolvedPathAWSPreference.data()); + return false; + } + + if (fileIO->Exists(resolvedPathAWSPreference.data())) + { + m_settingsRegistry->MergeSettingsFile(resolvedPathAWSPreference.data(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ""); + } + + bool awsAttributionEnabled = false; + if (!m_settingsRegistry->Get(awsAttributionEnabled, AWSAttributionEnabledKey)) + { + // If not found default to sending the metric. + awsAttributionEnabled = true; + } + + if (!awsAttributionEnabled) + { + return false; + } + + // If delayInSeconds is not found, set default to a day + AZ::u64 delayInSeconds = 0; + if (!m_settingsRegistry->Get(delayInSeconds, AWSAttributionDelaySecondsKey)) + { + AZ_Warning("AWSAttributionManager", false, "AWSAttribution delay key not found. Defaulting to delay to day"); + delayInSeconds = 86400; + m_settingsRegistry->Set(AWSAttributionDelaySecondsKey, delayInSeconds); + } + + AZ::u64 lastSendTimeStampSeconds = 0; + if (!m_settingsRegistry->Get(lastSendTimeStampSeconds, AWSAttributionLastTimeStampKey)) + { + // If last time stamp not found, assume this is the first attempt at sending. + return true; + } + + AZStd::chrono::seconds lastSendTimeStamp = AZStd::chrono::seconds(lastSendTimeStampSeconds); + AZStd::chrono::seconds secondsSinceLastSend = + AZStd::chrono::duration_cast(AZStd::chrono::system_clock::now().time_since_epoch()) - lastSendTimeStamp; + if (secondsSinceLastSend.count() >= delayInSeconds) + { + return true; + } + + return false; + } + + void AWSAttributionManager::SaveSettingsRegistryFile() + { + AZ::Job* job = AZ::CreateJobFunction( + [this]() + { + AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); + AZ_Assert(fileIO, "File IO is not initialized."); + + // Resolve path to editor_aws_preferences.setreg + AZStd::string editorPreferencesFilePath = AZStd::string::format("@user@/%s/%s", AZ::SettingsRegistryInterface::RegistryFolder, EditorAWSPreferencesFileName); + AZStd::array resolvedPath {}; + fileIO->ResolvePath(editorPreferencesFilePath.c_str(), resolvedPath.data(), resolvedPath.size()); + + AZ::SettingsRegistryMergeUtils::DumperSettings dumperSettings; + dumperSettings.m_prettifyOutput = true; + dumperSettings.m_jsonPointerPrefix = AWSAttributionSettingsPrefixKey; + + AZStd::string stringBuffer; + AZ::IO::ByteContainerStream stringStream(&stringBuffer); + if (!AZ::SettingsRegistryMergeUtils::DumpSettingsRegistryToStream( + *m_settingsRegistry, AWSAttributionSettingsPrefixKey, stringStream, dumperSettings)) + { + AZ_Warning( + "AWSAttributionManager", false, R"(Unable to save changes to the Editor AWS Preferences registry file at "%s"\n)", + resolvedPath.data()); + return; + } + + bool saved {}; + constexpr auto configurationMode = + AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY; + if (AZ::IO::SystemFile outputFile; outputFile.Open(resolvedPath.data(), configurationMode)) + { + saved = outputFile.Write(stringBuffer.data(), stringBuffer.size()) == stringBuffer.size(); + } + + AZ_Warning( + "AWSAttributionManager", saved, R"(Unable to save Editor AWS Preferences registry file to path "%s"\n)", + editorPreferencesFilePath.c_str()); + }, + true); + job->Start(); + + } + + void AWSAttributionManager::UpdateLastSend() + { + if (!m_settingsRegistry->Set(AWSAttributionLastTimeStampKey, + AZStd::chrono::duration_cast(AZStd::chrono::system_clock::now().time_since_epoch()).count())) + { + AZ_Warning("AWSAttributionManager", true, "Failed to set AWSAttributionLastTimeStamp"); + return; + } + SaveSettingsRegistryFile(); + } + + void AWSAttributionManager::SetApiEndpointAndRegion(AWSCore::ServiceAPI::AWSAttributionRequestJob::Config* config) + { + // Get default config for the process to check the region. + // Assumption to determine China region is the default profile is set to China region. + auto profile_name = Aws::Auth::GetConfigProfileName(); + Aws::Client::ClientConfiguration clientConfig(profile_name.c_str()); + AZStd::string apiId = AWSAttributionApiId; + + if (clientConfig.region == Aws::Region::CN_NORTH_1 || clientConfig.region == Aws::Region::CN_NORTHWEST_1) + { + config->region = Aws::Region::CN_NORTH_1; + apiId = AWSAttributionChinaApiId; + } + + config->region = Aws::Region::US_WEST_2; + config->endpointOverride = + AWSResourceMappingUtils::FormatRESTApiUrl(apiId, config->region.value().c_str(), AWSAttributionApiStage).c_str(); + } + + AZStd::string AWSAttributionManager::GetEngineVersion() const + { + AZStd::string engineVersion; + auto engineSettingsPath = AZ::IO::FixedMaxPath{ AZ::Utils::GetEnginePath() } / "engine.json"; + if (AZ::IO::SystemFile::Exists(engineSettingsPath.c_str())) + { + AZ::SettingsRegistryImpl settingsRegistry; + if (settingsRegistry.MergeSettingsFile( + engineSettingsPath.Native(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, AZ::SettingsRegistryMergeUtils::EngineSettingsRootKey)) + { + settingsRegistry.Get(engineVersion, AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::EngineSettingsRootKey) + "/" + EngineVersionJsonKey); + } + } + return engineVersion; + } + + AZStd::string AWSAttributionManager::GetPlatform() const + { + return AZ::GetPlatformName(AZ::g_currentPlatform); + } + + void AWSAttributionManager::GetActiveAWSGems(AZStd::vector& gems) + { + AZ::ModuleManagerRequestBus::Broadcast( + &AZ::ModuleManagerRequestBus::Events::EnumerateModules, + [this, &gems](const AZ::ModuleData& moduleData) + { + AZ::Entity* moduleEntity = moduleData.GetEntity(); + auto moduleEntityName = moduleEntity->GetName(); + if (moduleEntityName.contains("AWS")) + gems.push_back(moduleEntityName.substr(0, moduleEntityName.find_last_of("."))); + return true; + }); + } + + void AWSAttributionManager::UpdateMetric(AttributionMetric& metric) + { + AZStd::string engineVersion = this->GetEngineVersion(); + metric.SetO3DEVersion(engineVersion); + + AZStd::string platform = this->GetPlatform(); + metric.SetPlatform(platform, ""); + + AZStd::vector gemNames; + GetActiveAWSGems(gemNames); + for (AZStd::string& gemName : gemNames) + { + metric.AddActiveGem(gemName); + } + } + + void AWSAttributionManager::SubmitMetric(AttributionMetric& metric) + { + AWSCore::ServiceAPI::AWSAttributionRequestJob::Config* config = ServiceAPI::AWSAttributionRequestJob::GetDefaultConfig(); + SetApiEndpointAndRegion(config); + + ServiceAPI::AWSAttributionRequestJob* requestJob = ServiceAPI::AWSAttributionRequestJob::Create( + [this](ServiceAPI::AWSAttributionRequestJob* successJob) + { + AZ_UNUSED(successJob); + + UpdateLastSend(); + AZ_Printf("AWSAttributionManager", "AWSAttribution metric submit success"); + + }, {}, config); + + requestJob->parameters.metric = metric; + requestJob->Start(); + } + +} // namespace AWSCore diff --git a/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionMetric.cpp b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionMetric.cpp new file mode 100644 index 0000000000..6ad322995e --- /dev/null +++ b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionMetric.cpp @@ -0,0 +1,106 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include +#include +#include +#include + +#pragma warning(disable : 4996) + +namespace AWSCore +{ + AttributionMetric::AttributionMetric(const AZStd::string& timestamp) + : m_version("1.1") + , m_timestamp(timestamp) + { + } + + AttributionMetric::AttributionMetric() + : m_version("1.1") + { + m_timestamp = AttributionMetric::GenerateTimeStamp(); + } + + void AttributionMetric::SetO3DEVersion(const AZStd::string& version) + { + m_o3deVersion = version; + } + + void AttributionMetric::SetPlatform(const AZStd::string& platform, const AZStd::string& platformVersion) + { + m_platform = platform; + m_platformVersion = platformVersion; + } + + void AttributionMetric::AddActiveGem(const AZStd::string& gemName) + { + m_activeAWSGems.push_back(gemName); + } + + AZStd::string AttributionMetric::SerializeToJson() + { + std::stringstream stringStream; + AWSCore::JsonOutputStream jsonStream{stringStream}; + AWSCore::JsonWriter writer{jsonStream}; + + SerializeToJson(writer); + + return stringStream.str().c_str(); + } + + bool AttributionMetric::SerializeToJson(AWSCore::JsonWriter& writer) const + { + bool ok = true; + ok = ok && writer.StartObject(); + + writer.Write(AwsAttributionAttributeKeyVersion, m_version.c_str()); + writer.Write(AwsAttributionAttributeKeyO3DEVersion, m_o3deVersion.c_str()); + writer.Write(AwsAttributionAttributeKeyPlatform, m_platform.c_str()); + writer.Write(AwsAttributionAttributeKeyPlatformVersion, m_platformVersion.c_str()); + + if (m_activeAWSGems.size() > 0) + { + writer.Key(AwsAttributionAttributeKeyActiveAWSGems); + writer.StartArray(); // to store Array of objects + for (auto& iter : m_activeAWSGems) + { + writer.String(iter.c_str()); + } + writer.EndArray(); + } + + writer.Write(AwsAttributionAttributeKeyTimestamp, m_timestamp.c_str()); + + ok = ok && writer.EndObject(); + return ok; + } + + bool AttributionMetric::ReadFromJson(rapidjson::Value& metricsObjVal) + { + AZ_UNUSED(metricsObjVal); + return false; + } + + AZStd::string AttributionMetric::GenerateTimeStamp() + { + // Timestamp format is using the UTC ISO8601 format + // TODO: Move to a general util as Metrics has similar requirement + time_t now; + time(&now); + char buffer[50]; + strftime(buffer, sizeof(buffer), "%FT%TZ", gmtime(&now)); + + return buffer; + } + +} // namespace AWSCore diff --git a/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionSystemComponent.cpp b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionSystemComponent.cpp new file mode 100644 index 0000000000..ea388972d3 --- /dev/null +++ b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionSystemComponent.cpp @@ -0,0 +1,81 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace AWSCore +{ + + AWSAttributionSystemComponent::AWSAttributionSystemComponent() + : m_manager(AZStd::make_unique()) + { + } + + void AWSAttributionSystemComponent::Reflect(AZ::ReflectContext* context) + { + if (AZ::SerializeContext* serialize = azrtti_cast(context)) + { + serialize->Class()->Version(0); + if (AZ::EditContext* ec = serialize->GetEditContext()) + { + ec->Class("AWSCoreAttributions", "Generates operation metrics for AWSCore gem") + ->ClassElement(AZ::Edit::ClassElements::EditorData, ""); + } + } + } + + void AWSAttributionSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) + { + provided.push_back(AZ_CRC_CE("AWSCoreAttributionService")); + } + + void AWSAttributionSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC_CE("AWSCoreAttributionService")); + } + + void AWSAttributionSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) + { + required.push_back(AZ_CRC_CE("AWSCoreService")); + } + + void AWSAttributionSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) + { + AZ_UNUSED(dependent); + } + + void AWSAttributionSystemComponent::Init() + { + // load config if required - ie check if attributions should be generated and pass to manager + m_manager->Init(); + } + + void AWSAttributionSystemComponent::Activate() + { + m_manager->MetricCheck(); + } + + void AWSAttributionSystemComponent::Deactivate() + { + m_manager.reset(); + } + +} // namespace AWSCore + diff --git a/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSAttributionServiceApiTest.cpp b/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSAttributionServiceApiTest.cpp new file mode 100644 index 0000000000..affa1ad69c --- /dev/null +++ b/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSAttributionServiceApiTest.cpp @@ -0,0 +1,85 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include +#include +#include +#include + +#include + +using namespace AWSCore; + +namespace AWSCoreUnitTest +{ + class JsonReaderMock + : public AWSCore::JsonReader + { + public: + MOCK_METHOD0(Ignore, bool()); + MOCK_METHOD1(Accept, bool(bool& target)); + MOCK_METHOD1(Accept, bool(AZStd::string& target)); + MOCK_METHOD1(Accept, bool(int& target)); + MOCK_METHOD1(Accept, bool(unsigned& target)); + MOCK_METHOD1(Accept, bool(int64_t& target)); + MOCK_METHOD1(Accept, bool(uint64_t& target)); + MOCK_METHOD1(Accept, bool(double& target)); + MOCK_METHOD1(Accept, bool(AWSCore::JsonKeyHandler keyHandler)); + MOCK_METHOD1(Accept, bool(AWSCore::JsonArrayHandler arrayHandler)); + }; + + class AWSAttributionServiceApiTest + : public UnitTest::ScopedAllocatorSetupFixture + { + public: + testing::NiceMock JsonReader; + }; + + TEST_F(AWSAttributionServiceApiTest, AWSAtrributionSuccessResponse_Serialization) + { + ServiceAPI::AWSAtrributionSuccessResponse response; + response.result = "ok"; + + EXPECT_CALL(JsonReader, Accept(response.result)).Times(1); + EXPECT_CALL(JsonReader, Ignore()).Times(0); + + response.OnJsonKey("statusCode", JsonReader); + } + + TEST_F(AWSAttributionServiceApiTest, AWSAtrributionSuccessResponse_Serialization_Ignore) + { + ServiceAPI::AWSAtrributionSuccessResponse response; + response.result = "ok"; + + EXPECT_CALL(JsonReader, Accept(response.result)).Times(0); + EXPECT_CALL(JsonReader, Ignore()).Times(1); + + response.OnJsonKey("", JsonReader); + } + + TEST_F(AWSAttributionServiceApiTest, BuildRequestBody_PostProducerEventsRequest_SerializedMetricsQueue) + { + ServiceAPI::AWSAttributionRequest request; + request.parameters.metric = AttributionMetric(); + + AWSCore::RequestBuilder requestBuilder{}; + EXPECT_TRUE(request.parameters.BuildRequest(requestBuilder)); + std::shared_ptr bodyContent = requestBuilder.GetBodyContent(); + EXPECT_TRUE(bodyContent != nullptr); + + AZStd::string bodyString; + std::istreambuf_iterator eos; + bodyString = AZStd::string{ std::istreambuf_iterator(*bodyContent), eos }; + AZ_Printf("AWSAttributionServiceApiTest", bodyString.c_str()); + EXPECT_TRUE(bodyString.find(AZStd::string::format("{\"%s\":\"1.1\"", AwsAttributionAttributeKeyVersion)) != AZStd::string::npos); + } +} diff --git a/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionManagerTest.cpp b/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionManagerTest.cpp new file mode 100644 index 0000000000..298c250086 --- /dev/null +++ b/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionManagerTest.cpp @@ -0,0 +1,414 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +using namespace AWSCore; + +namespace AWSAttributionUnitTest +{ + class ModuleDataMock: + public AZ::ModuleData + { + public: + AZStd::shared_ptr m_entity; + ModuleDataMock(AZStd::string name) + { + m_entity = AZStd::make_shared(); + m_entity->SetName(name); + } + virtual ~ModuleDataMock() + { + m_entity.reset(); + } + + AZ::DynamicModuleHandle* GetDynamicModuleHandle() const override + { + return nullptr; + } + /// Get the handle to the module class + AZ::Module* GetModule() const override + { + return nullptr; + } + /// Get the entity this module uses as a System Entity + AZ::Entity* GetEntity() const override + { + return m_entity.get(); + } + /// Get the debug name of the module + const char* GetDebugName() const override + { + return m_entity->GetName().c_str(); + } + }; + + class ModuleManagerRequestBusMock + : public AZ::ModuleManagerRequestBus::Handler + { + public: + + void EnumerateModulesMock(AZ::ModuleManagerRequests::EnumerateModulesCallback perModuleCallback) + { + auto data = ModuleDataMock("AWSCore.Editor.dll"); + perModuleCallback(data); + data = ModuleDataMock("AWSClientAuth.so"); + perModuleCallback(data); + } + + ModuleManagerRequestBusMock() + { + AZ::ModuleManagerRequestBus::Handler::BusConnect(); + ON_CALL(*this, EnumerateModules(testing::_)).WillByDefault(testing::Invoke(this, &ModuleManagerRequestBusMock::EnumerateModulesMock)); + } + + ~ModuleManagerRequestBusMock() + { + AZ::ModuleManagerRequestBus::Handler::BusDisconnect(); + } + + MOCK_METHOD1(EnumerateModules, void(AZ::ModuleManagerRequests::EnumerateModulesCallback perModuleCallback)); + MOCK_METHOD3(LoadDynamicModule, AZ::ModuleManagerRequests::LoadModuleOutcome(const char* modulePath, AZ::ModuleInitializationSteps lastStepToPerform, bool maintainReference)); + MOCK_METHOD3(LoadDynamicModules, AZ::ModuleManagerRequests::LoadModulesResult(const AZ::ModuleDescriptorList& modules, AZ::ModuleInitializationSteps lastStepToPerform, bool maintainReferences)); + MOCK_METHOD2(LoadStaticModules, AZ::ModuleManagerRequests::LoadModulesResult(AZ::CreateStaticModulesCallback staticModulesCb, AZ::ModuleInitializationSteps lastStepToPerform)); + MOCK_METHOD1(IsModuleLoaded, bool(const char* modulePath)); + }; + + class AWSAttributionManagerMock + : public AWSAttributionManager + { + public: + using AWSAttributionManager::SubmitMetric; + using AWSAttributionManager::UpdateMetric; + using AWSAttributionManager::SetApiEndpointAndRegion; + + + AWSAttributionManagerMock() + { + ON_CALL(*this, SubmitMetric(testing::_)).WillByDefault(testing::Invoke(this, &AWSAttributionManagerMock::SubmitMetricMock)); + } + + MOCK_METHOD1(SubmitMetric, void(AttributionMetric& metric)); + + void SubmitMetricMock(AttributionMetric& metric) + { + AZ_UNUSED(metric); + UpdateLastSend(); + } + }; + + class AttributionManagerTest + : public AWSCoreFixture + { + public: + + virtual ~AttributionManagerTest() = default; + + protected: + AZStd::shared_ptr m_serializeContext; + AZStd::unique_ptr m_registrationContext; + AZStd::shared_ptr m_settingsRegistry; + AZStd::unique_ptr m_jobContext; + AZStd::unique_ptr m_jobCancelGroup; + AZStd::unique_ptr m_jobManager; + AZStd::array m_resolvedSettingsPath; + ModuleManagerRequestBusMock m_moduleManagerRequestBusMock; + + void SetUp() override + { + AWSCoreFixture::SetUp(); + + char rootPath[AZ_MAX_PATH_LEN]; + AZ::Utils::GetExecutableDirectory(rootPath, AZ_MAX_PATH_LEN); + m_localFileIO->SetAlias("@user@", AZ_TRAIT_TEST_ROOT_FOLDER); + + m_localFileIO->ResolvePath("@user@/Registry/", m_resolvedSettingsPath.data(), m_resolvedSettingsPath.size()); + AZ::IO::SystemFile::CreateDir(m_resolvedSettingsPath.data()); + + m_localFileIO->ResolvePath("@user@/Registry/editor_aws_preferences.setreg", m_resolvedSettingsPath.data(), m_resolvedSettingsPath.size()); + + m_serializeContext = AZStd::make_unique(); + + AZ::JsonSystemComponent::Reflect(m_registrationContext.get()); + + m_settingsRegistry = AZStd::make_unique(); + + m_settingsRegistry->SetContext(m_serializeContext.get()); + m_settingsRegistry->SetContext(m_registrationContext.get()); + + AZ::SettingsRegistry::Register(m_settingsRegistry.get()); + + AZ::JobManagerDesc jobManagerDesc; + AZ::JobManagerThreadDesc threadDesc; + + m_jobManager.reset(aznew AZ::JobManager(jobManagerDesc)); + m_jobCancelGroup.reset(aznew AZ::JobCancelGroup()); + jobManagerDesc.m_workerThreads.push_back(threadDesc); + m_jobContext.reset(aznew AZ::JobContext(*m_jobManager, *m_jobCancelGroup)); + AZ::JobContext::SetGlobalContext(m_jobContext.get()); + } + + void TearDown() override + { + AZ::JobContext::SetGlobalContext(nullptr); + m_jobContext.reset(); + m_jobCancelGroup.reset(); + m_jobManager.reset(); + + AZ::SettingsRegistry::Unregister(m_settingsRegistry.get()); + + m_settingsRegistry.reset(); + m_serializeContext.reset(); + m_registrationContext.reset(); + + m_localFileIO->ResolvePath("@user@/Registry/", m_resolvedSettingsPath.data(), m_resolvedSettingsPath.size()); + AZ::IO::SystemFile::DeleteDir(m_resolvedSettingsPath.data()); + + delete AZ::IO::FileIOBase::GetInstance(); + AZ::IO::FileIOBase::SetInstance(nullptr); + + AWSCoreFixture::TearDown(); + } + }; + + TEST_F(AttributionManagerTest, MetricsSettings_AttributionDisabled_SkipsSend) + { + // GIVEN + AWSAttributionManagerMock manager; + manager.Init(); + + CreateFile(m_resolvedSettingsPath.data(), R"({ + "Amazon": { + "AWS": { + "Preferences": { + "AWSAttributionEnabled": false, + "AWSAttributionDelaySeconds": 30 + } + } + } + })"); + + EXPECT_CALL(manager, SubmitMetric(testing::_)).Times(0); + EXPECT_CALL(m_moduleManagerRequestBusMock, EnumerateModules(testing::_)).Times(0); + + // WHEN + manager.MetricCheck(); + + // THEN + m_settingsRegistry->MergeSettingsFile(m_resolvedSettingsPath.data(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ""); + AZ::u64 timeStamp = 0; + m_settingsRegistry->Get(timeStamp, "/Amazon/AWS/Preferences/AWSAttributionLastTimeStamp"); + ASSERT_TRUE(timeStamp == 0); + + RemoveFile(m_resolvedSettingsPath.data()); + } + + TEST_F(AttributionManagerTest, AttributionEnabled_NoPreviousTimeStamp_SendSuccess) + { + // GIVEN + AWSAttributionManagerMock manager; + manager.Init(); + + CreateFile(m_resolvedSettingsPath.data(), R"({ + "Amazon": { + "AWS": { + "Preferences": { + "AWSAttributionEnabled": true, + "AWSAttributionDelaySeconds": 30, + } + } + } + })"); + + EXPECT_CALL(manager, SubmitMetric(testing::_)).Times(1); + EXPECT_CALL(m_moduleManagerRequestBusMock, EnumerateModules(testing::_)).Times(1); + + // WHEN + manager.MetricCheck(); + + // THEN + m_settingsRegistry->MergeSettingsFile(m_resolvedSettingsPath.data(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ""); + AZ::u64 timeStamp = 0; + m_settingsRegistry->Get(timeStamp, "/Amazon/AWS/Preferences/AWSAttributionLastTimeStamp"); + ASSERT_TRUE(timeStamp > 0); + + + RemoveFile(m_resolvedSettingsPath.data()); + } + + TEST_F(AttributionManagerTest, AttributionEnabled_ValidPreviousTimeStamp_SendSuccess) + { + // GIVEN + AWSAttributionManagerMock manager; + manager.Init(); + + CreateFile(m_resolvedSettingsPath.data(), R"({ + "Amazon": { + "AWS": { + "Preferences": { + "AWSAttributionEnabled": true, + "AWSAttributionDelaySeconds": 30, + "AWSAttributionLastTimeStamp": 629400 + } + } + } + })"); + + EXPECT_CALL(manager, SubmitMetric(testing::_)).Times(1); + EXPECT_CALL(m_moduleManagerRequestBusMock, EnumerateModules(testing::_)).Times(1); + + // WHEN + manager.MetricCheck(); + + // THEN + m_settingsRegistry->MergeSettingsFile(m_resolvedSettingsPath.data(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ""); + AZ::u64 timeStamp = 0; + m_settingsRegistry->Get(timeStamp, "/Amazon/AWS/Preferences/AWSAttributionLastTimeStamp"); + ASSERT_TRUE(timeStamp > 0); + + RemoveFile(m_resolvedSettingsPath.data()); + } + + TEST_F(AttributionManagerTest, AttributionEnabled_DelayNotSatisfied_SendFail) + { + // GIVEN + AWSAttributionManagerMock manager; + manager.Init(); + + + CreateFile(m_resolvedSettingsPath.data(), R"({ + "Amazon": { + "AWS": { + "Preferences": { + "AWSAttributionEnabled": true, + "AWSAttributionDelaySeconds": 300, + "AWSAttributionLastTimeStamp": 0 + } + } + } + })"); + + AZ::u64 delayInSeconds = AZStd::chrono::duration_cast(AZStd::chrono::system_clock::now().time_since_epoch()).count(); + ASSERT_TRUE(m_settingsRegistry->Set("/Amazon/AWS/Preferences/AWSAttributionLastTimeStamp", delayInSeconds)); + + EXPECT_CALL(manager, SubmitMetric(testing::_)).Times(1); + EXPECT_CALL(m_moduleManagerRequestBusMock, EnumerateModules(testing::_)).Times(1); + + // WHEN + manager.MetricCheck(); + + // THEN + m_settingsRegistry->MergeSettingsFile(m_resolvedSettingsPath.data(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ""); + AZ::u64 timeStamp = 0; + m_settingsRegistry->Get(timeStamp, "/Amazon/AWS/Preferences/AWSAttributionLastTimeStamp"); + ASSERT_TRUE(timeStamp == delayInSeconds); + + RemoveFile(m_resolvedSettingsPath.data()); + } + + TEST_F(AttributionManagerTest, AttributionEnabledNotFound_SendSuccess) + { + // GIVEN + AWSAttributionManagerMock manager; + manager.Init(); + + CreateFile(m_resolvedSettingsPath.data(), R"({ + "Amazon": { + "AWS": { + "Preferences": { + } + } + } + })"); + + EXPECT_CALL(manager, SubmitMetric(testing::_)).Times(1); + EXPECT_CALL(m_moduleManagerRequestBusMock, EnumerateModules(testing::_)).Times(1); + + // WHEN + manager.MetricCheck(); + + // THEN + m_settingsRegistry->MergeSettingsFile(m_resolvedSettingsPath.data(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ""); + AZ::u64 timeStamp = 0; + m_settingsRegistry->Get(timeStamp, "/Amazon/AWS/Preferences/AWSAttributionLastTimeStamp"); + ASSERT_TRUE(timeStamp != 0); + + RemoveFile(m_resolvedSettingsPath.data()); + } + + TEST_F(AttributionManagerTest, SetApiEndpointAndRegion_Success) + { + // GIVEN + AWSAttributionManagerMock manager; + AWSCore::ServiceAPI::AWSAttributionRequestJob::Config* config = aznew AWSCore::ServiceAPI::AWSAttributionRequestJob::Config(); + + // WHEN + manager.SetApiEndpointAndRegion(config); + + // THEN + ASSERT_TRUE(config->region == Aws::Region::US_WEST_2); + ASSERT_TRUE(config->endpointOverride->find("execute-api.us-west-2.amazonaws.com") != Aws::String::npos); + + delete config; + } + + TEST_F(AttributionManagerTest, UpdateMetric_Success) + { + // GIVEN + AWSAttributionManagerMock manager; + AttributionMetric metric; + + AZStd::array engineJsonPath; + m_localFileIO->ResolvePath("@user@/Registry/engine.json", engineJsonPath.data(), engineJsonPath.size()); + CreateFile(engineJsonPath.data(), R"({"O3DEVersion": "1.0.0.0"})"); + + m_localFileIO->ResolvePath("@user@/Registry/", engineJsonPath.data(), engineJsonPath.size()); + m_settingsRegistry->Set(AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder, engineJsonPath.data()); + + EXPECT_CALL(m_moduleManagerRequestBusMock, EnumerateModules(testing::_)).Times(1); + + // WHEN + manager.UpdateMetric(metric); + + // THEN + AZStd::string serializedMetricValue = metric.SerializeToJson(); + ASSERT_TRUE(serializedMetricValue.find("\"o3de_version\":\"1.0.0.0\"") != AZStd::string::npos); + ASSERT_TRUE(serializedMetricValue.find(AZ::GetPlatformName(AZ::g_currentPlatform)) != AZStd::string::npos); + ASSERT_TRUE(serializedMetricValue.find("AWSCore.Editor") != AZStd::string::npos); + ASSERT_TRUE(serializedMetricValue.find("AWSClientAuth") != AZStd::string::npos); + + RemoveFile(engineJsonPath.data()); + } + +} // namespace AWSCoreUnitTest diff --git a/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionMetricTest.cpp b/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionMetricTest.cpp new file mode 100644 index 0000000000..c93b8bb08e --- /dev/null +++ b/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionMetricTest.cpp @@ -0,0 +1,50 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include + +#include + +namespace AWSCore +{ + using AttributionMetricTest = UnitTest::ScopedAllocatorSetupFixture; + + TEST_F(AttributionMetricTest, Contruction_Test) + { + AZStd::string timestamp = AttributionMetric::GenerateTimeStamp(); + AttributionMetric metric(timestamp); + + AZStd::string serializedMetric = AZStd::string::format( + "{\"version\":\"1.1\",\"o3de_version\":\"\",\"platform\":\"\",\"platform_version\":\"\",\"timestamp\":\"%s\"}", timestamp.c_str()); + ASSERT_EQ(metric.SerializeToJson(), serializedMetric); + } + + TEST_F(AttributionMetricTest, AddActiveGems) + { + AZStd::string timestamp = AttributionMetric::GenerateTimeStamp(); + AttributionMetric metric(timestamp); + + AZStd::string gem1 = "AWSGem1"; + AZStd::string gem2 = "AWSGem2"; + + metric.AddActiveGem(gem1); + metric.AddActiveGem(gem2); + + AZStd::string serializedMetric = AZStd::string::format( + "{\"version\":\"1.1\",\"o3de_version\":\"\",\"platform\":\"\",\"platform_version\":\"\",\"aws_gems\":[\"%s\",\"%s\"],\"timestamp\":\"%s\"}", + gem1.c_str(), gem2.c_str(), timestamp.c_str()); + + AZStd::string actualValue = metric.SerializeToJson(); + ASSERT_EQ(actualValue, serializedMetric); + } + +} // namespace AWSCore diff --git a/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionSystemComponentTest.cpp b/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionSystemComponentTest.cpp new file mode 100644 index 0000000000..4419c78467 --- /dev/null +++ b/Gems/AWSCore/Code/Tests/Editor/Attribution/AWSCoreAttributionSystemComponentTest.cpp @@ -0,0 +1,132 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace AWSCore; + +namespace AWSCoreUnitTest +{ + class AWSCoreSystemComponentMock : public AZ::Component + { + public: + AZ_COMPONENT(AWSCoreSystemComponentMock, "{5F48030D-EB59-4820-BC65-69EC7CC6C119}"); + + static void Reflect(AZ::ReflectContext* context) + { + if (AZ::SerializeContext* serialize = azrtti_cast(context)) + { + serialize->Class()->Version(0); + + if (AZ::EditContext* ec = serialize->GetEditContext()) + { + ec->Class("AWSCoreMock", "Adds core support for working with AWS") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System")) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true); + } + } + } + + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) + { + provided.push_back(AZ_CRC_CE("AWSCoreService")); + } + + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + AZ_UNUSED(incompatible); + } + static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) + { + AZ_UNUSED(required); + } + static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) + { + AZ_UNUSED(dependent); + } + + ~AWSCoreSystemComponentMock() = default; + + MOCK_METHOD0(Init, void()); + MOCK_METHOD0(Activate, void()); + MOCK_METHOD0(Deactivate, void()); + }; + + class AWSAttributionSystemComponentTest : public AWSCoreFixture + { + void SetUp() override + { + AWSCoreFixture::SetUp(); + m_serializeContext = AZStd::make_unique(); + m_serializeContext->CreateEditContext(); + m_behaviorContext = AZStd::make_unique(); + + m_awsCoreComponentDescriptor.reset(AWSCoreSystemComponentMock::CreateDescriptor()); + m_awsCoreComponentDescriptor->Reflect(m_serializeContext.get()); + m_awsCoreComponentDescriptor->Reflect(m_behaviorContext.get()); + + m_componentDescriptor.reset(AWSAttributionSystemComponent::CreateDescriptor()); + m_componentDescriptor->Reflect(m_serializeContext.get()); + m_componentDescriptor->Reflect(m_behaviorContext.get()); + + m_entity = aznew AZ::Entity(); + m_awsCoreSystemComponentMock = aznew testing::NiceMock(); + m_entity->AddComponent(m_awsCoreSystemComponentMock); + m_attributionSystemsComponent.reset(m_entity->CreateComponent()); + } + + void TearDown() override + { + m_entity->Deactivate(); + m_entity->RemoveComponent(m_attributionSystemsComponent.get()); + m_entity->RemoveComponent(m_awsCoreSystemComponentMock); + delete m_entity; + m_entity = nullptr; + + m_attributionSystemsComponent.reset(); + delete m_awsCoreSystemComponentMock; + m_awsCoreComponentDescriptor.reset(); + m_componentDescriptor.reset(); + m_behaviorContext.reset(); + m_serializeContext.reset(); + AWSCoreFixture::TearDown(); + } + + public: + AZStd::unique_ptr m_attributionSystemsComponent; + testing::NiceMock* m_awsCoreSystemComponentMock; + AZ::Entity* m_entity; + + private: + AZStd::unique_ptr m_serializeContext; + AZStd::unique_ptr m_behaviorContext; + AZStd::unique_ptr m_componentDescriptor; + AZStd::unique_ptr m_awsCoreComponentDescriptor; + }; + + TEST_F(AWSAttributionSystemComponentTest, SystemComponentInitActivate_Success) + { + m_entity->Init(); + m_entity->Activate(); + } +} + + diff --git a/Gems/AWSCore/Code/Tests/TestFramework/AWSCoreFixture.h b/Gems/AWSCore/Code/Tests/TestFramework/AWSCoreFixture.h index 1810af9c82..d921ffaf07 100644 --- a/Gems/AWSCore/Code/Tests/TestFramework/AWSCoreFixture.h +++ b/Gems/AWSCore/Code/Tests/TestFramework/AWSCoreFixture.h @@ -127,13 +127,40 @@ public: void TearDown() override { AZ::IO::FileIOBase::SetInstance(nullptr); - delete m_localFileIO; - AZ::IO::FileIOBase::SetInstance(m_otherFileIO); + + if (m_otherFileIO) + { + delete m_localFileIO; + AZ::IO::FileIOBase::SetInstance(m_otherFileIO); + } AZ::AllocatorInstance::Destroy(); AZ::AllocatorInstance::Destroy(); } + bool CreateFile(const AZStd::string& filePath, const AZStd::string& content) + { + AZ::IO::HandleType fileHandle; + if (!m_localFileIO->Open(filePath.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText, fileHandle)) + { + return false; + } + + m_localFileIO->Write(fileHandle, content.c_str(), content.size()); + m_localFileIO->Close(fileHandle); + return true; + } + + bool RemoveFile(const AZStd::string& filePath) + { + if (m_localFileIO->Exists(filePath.c_str())) + { + return m_localFileIO->Remove(filePath.c_str()); + } + + return true; + } + AZ::IO::FileIOBase* m_localFileIO = nullptr; private: diff --git a/Gems/AWSCore/Code/awscore_editor_files.cmake b/Gems/AWSCore/Code/awscore_editor_files.cmake index 13bfbb6102..6e16fc7d27 100644 --- a/Gems/AWSCore/Code/awscore_editor_files.cmake +++ b/Gems/AWSCore/Code/awscore_editor_files.cmake @@ -11,6 +11,11 @@ set(FILES Include/Private/AWSCoreEditorSystemComponent.h + Include/Private/Editor/Attribution/AWSCoreAttributionConstant.h + Include/Private/Editor/Attribution/AWSCoreAttributionMetric.h + Include/Private/Editor/Attribution/AWSCoreAttributionManager.h + Include/Private/Editor/Attribution/AWSCoreAttributionSystemComponent.h + Include/Private/Editor/Attribution/AWSAttributionServiceApi.h Include/Private/Editor/AWSCoreEditorManager.h Include/Private/Editor/Constants/AWSCoreEditorMenuLinks.h Include/Private/Editor/Constants/AWSCoreEditorMenuNames.h @@ -18,6 +23,10 @@ set(FILES Include/Private/Editor/UI/AWSCoreResourceMappingToolAction.h Source/AWSCoreEditorSystemComponent.cpp Source/Editor/AWSCoreEditorManager.cpp + Source/Editor/Attribution/AWSCoreAttributionMetric.cpp + Source/Editor/Attribution/AWSCoreAttributionManager.cpp + Source/Editor/Attribution/AWSCoreAttributionSystemComponent.cpp + Source/Editor/Attribution/AWSAttributionServiceApi.cpp Source/Editor/UI/AWSCoreEditorMenu.cpp Source/Editor/UI/AWSCoreResourceMappingToolAction.cpp ) diff --git a/Gems/AWSCore/Code/awscore_editor_tests_files.cmake b/Gems/AWSCore/Code/awscore_editor_tests_files.cmake index ff89b6b5bd..bba830d5d1 100644 --- a/Gems/AWSCore/Code/awscore_editor_tests_files.cmake +++ b/Gems/AWSCore/Code/awscore_editor_tests_files.cmake @@ -11,6 +11,10 @@ set(FILES Tests/AWSCoreEditorSystemComponentTest.cpp + Tests/Editor/Attribution/AWSCoreAttributionManagerTest.cpp + Tests/Editor/Attribution/AWSCoreAttributionMetricTest.cpp + Tests/Editor/Attribution/AWSCoreAttributionSystemComponentTest.cpp + Tests/Editor/Attribution/AWSAttributionServiceApiTest.cpp Tests/Editor/UI/AWSCoreEditorMenuTest.cpp Tests/Editor/UI/AWSCoreEditorUIFixture.h Tests/Editor/UI/AWSCoreResourceMappingToolActionTest.cpp From aeaf1bcdbe6768ba0f4ef3e7afd603a899d3474c Mon Sep 17 00:00:00 2001 From: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> Date: Fri, 4 Jun 2021 21:29:36 -0700 Subject: [PATCH 10/15] Fix engine settings not populating or saving * Allow multiple settings to be registered at once * Old manifests versions may not have default_third_party_folder --- .../ProjectManager/Source/PythonBindings.cpp | 4 +- scripts/o3de/o3de/register.py | 50 +++++++++---------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/Code/Tools/ProjectManager/Source/PythonBindings.cpp b/Code/Tools/ProjectManager/Source/PythonBindings.cpp index 5f4bb833d8..d7d0414c1f 100644 --- a/Code/Tools/ProjectManager/Source/PythonBindings.cpp +++ b/Code/Tools/ProjectManager/Source/PythonBindings.cpp @@ -384,7 +384,9 @@ namespace O3DE::ProjectManager engineInfo.m_defaultProjectsFolder = Py_To_String(o3deData["default_projects_folder"]); engineInfo.m_defaultRestrictedFolder = Py_To_String(o3deData["default_restricted_folder"]); engineInfo.m_defaultTemplatesFolder = Py_To_String(o3deData["default_templates_folder"]); - engineInfo.m_thirdPartyPath = Py_To_String(o3deData["default_third_party_folder"]); + + pybind11::str defaultThirdPartyFolder = m_manifest.attr("get_o3de_third_party_folder")(); + engineInfo.m_thirdPartyPath = Py_To_String_Optional(o3deData,"default_third_party_folder", Py_To_String(defaultThirdPartyFolder)); } auto engineData = m_manifest.attr("get_engine_json_data")(pybind11::none(), enginePath); diff --git a/scripts/o3de/o3de/register.py b/scripts/o3de/o3de/register.py index 4e73edca7f..b3a6a1e44c 100644 --- a/scripts/o3de/o3de/register.py +++ b/scripts/o3de/o3de/register.py @@ -580,65 +580,65 @@ def register(engine_path: str or pathlib.Path = None, if not project_path: logger.error(f'Project path cannot be empty.') return 1 - result = register_project_path(json_data, project_path, remove, engine_path) + result = result or register_project_path(json_data, project_path, remove, engine_path) - elif isinstance(gem_path, str) or isinstance(gem_path, pathlib.PurePath): + if isinstance(gem_path, str) or isinstance(gem_path, pathlib.PurePath): if not gem_path: logger.error(f'Gem path cannot be empty.') return 1 - result = register_gem_path(json_data, gem_path, remove, + result = result or register_gem_path(json_data, gem_path, remove, external_subdir_engine_path, external_subdir_project_path) - elif isinstance(external_subdir_path, str) or isinstance(external_subdir_path, pathlib.PurePath): + if isinstance(external_subdir_path, str) or isinstance(external_subdir_path, pathlib.PurePath): if not external_subdir_path: logger.error(f'External Subdirectory path is None.') return 1 - result = register_external_subdirectory(json_data, external_subdir_path, remove, + result = result or register_external_subdirectory(json_data, external_subdir_path, remove, external_subdir_engine_path, external_subdir_project_path) - elif isinstance(template_path, str) or isinstance(template_path, pathlib.PurePath): + if isinstance(template_path, str) or isinstance(template_path, pathlib.PurePath): if not template_path: logger.error(f'Template path cannot be empty.') return 1 - result = register_template_path(json_data, template_path, remove, engine_path) + result = result or register_template_path(json_data, template_path, remove, engine_path) - elif isinstance(restricted_path, str) or isinstance(restricted_path, pathlib.PurePath): + if isinstance(restricted_path, str) or isinstance(restricted_path, pathlib.PurePath): if not restricted_path: logger.error(f'Restricted path cannot be empty.') return 1 - result = register_restricted_path(json_data, restricted_path, remove, engine_path) + result = result or register_restricted_path(json_data, restricted_path, remove, engine_path) - elif isinstance(repo_uri, str) or isinstance(repo_uri, pathlib.PurePath): + if isinstance(repo_uri, str) or isinstance(repo_uri, pathlib.PurePath): if not repo_uri: logger.error(f'Repo URI cannot be empty.') return 1 - result = register_repo(json_data, repo_uri, remove) + result = result or register_repo(json_data, repo_uri, remove) - elif isinstance(default_engines_folder, str) or isinstance(default_engines_folder, pathlib.PurePath): - result = register_default_engines_folder(json_data, default_engines_folder, remove) + if isinstance(default_engines_folder, str) or isinstance(default_engines_folder, pathlib.PurePath): + result = result or register_default_engines_folder(json_data, default_engines_folder, remove) - elif isinstance(default_projects_folder, str) or isinstance(default_projects_folder, pathlib.PurePath): - result = register_default_projects_folder(json_data, default_projects_folder, remove) + if isinstance(default_projects_folder, str) or isinstance(default_projects_folder, pathlib.PurePath): + result = result or register_default_projects_folder(json_data, default_projects_folder, remove) - elif isinstance(default_gems_folder, str) or isinstance(default_gems_folder, pathlib.PurePath): - result = register_default_gems_folder(json_data, default_gems_folder, remove) + if isinstance(default_gems_folder, str) or isinstance(default_gems_folder, pathlib.PurePath): + result = result or register_default_gems_folder(json_data, default_gems_folder, remove) - elif isinstance(default_templates_folder, str) or isinstance(default_templates_folder, pathlib.PurePath): - result = register_default_templates_folder(json_data, default_templates_folder, remove) + if isinstance(default_templates_folder, str) or isinstance(default_templates_folder, pathlib.PurePath): + result = result or register_default_templates_folder(json_data, default_templates_folder, remove) - elif isinstance(default_restricted_folder, str) or isinstance(default_restricted_folder, pathlib.PurePath): - result = register_default_restricted_folder(json_data, default_restricted_folder, remove) + if isinstance(default_restricted_folder, str) or isinstance(default_restricted_folder, pathlib.PurePath): + result = result or register_default_restricted_folder(json_data, default_restricted_folder, remove) - elif default_third_party_folder: - result = register_default_third_party_folder(json_data, default_third_party_folder, remove) + if isinstance(default_third_party_folder, str) or isinstance(default_third_party_folder, pathlib.PurePath): + result = result or register_default_third_party_folder(json_data, default_third_party_folder, remove) # engine is done LAST # Now that everything that could have an engine context is done, if the engine is supplied that means this is # registering the engine itself - elif isinstance(engine_path, str) or isinstance(engine_path, pathlib.PurePath): + if isinstance(engine_path, str) or isinstance(engine_path, pathlib.PurePath): if not engine_path: logger.error(f'Engine path cannot be empty.') return 1 - result = register_engine_path(json_data, engine_path, remove, force) + result = result or register_engine_path(json_data, engine_path, remove, force) if not result: manifest.save_o3de_manifest(json_data) From 1ffcfa07e6126c60e035a65f77bb7107d21b86dc Mon Sep 17 00:00:00 2001 From: Ibtehaj Nadeem <81370835+ibtehajn@users.noreply.github.com> Date: Mon, 7 Jun 2021 12:53:07 +0100 Subject: [PATCH 11/15] Remove Jenkins failure notifications (#958) Remove Jenkins failure notifications --- scripts/build/Jenkins/Jenkinsfile | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/scripts/build/Jenkins/Jenkinsfile b/scripts/build/Jenkins/Jenkinsfile index 3cf7d92ba6..1bce2988bf 100644 --- a/scripts/build/Jenkins/Jenkinsfile +++ b/scripts/build/Jenkins/Jenkinsfile @@ -578,14 +578,12 @@ finally { ) } node('controller') { - emailRecipients = [[$class: 'RequesterRecipientProvider']] - if (env.WATCHED_BRANCHES.tokenize(',').contains(branchName)) { - emailRecipients.add([$class: 'CulpritsRecipientProvider']) - } step([ - $class: 'Mailer', - notifyEveryUnstableBuild: true, - recipients: emailextrecipients(emailRecipients) + $class: 'Mailer', + notifyEveryUnstableBuild: true, + recipients: emailextrecipients([ + [$class: 'RequesterRecipientProvider'] + ]) ]) } } catch(Exception e) { From 5b940e8ed671034fa1ffb5e6950e752d88542ef2 Mon Sep 17 00:00:00 2001 From: Hasareej <82398396+Hasareej@users.noreply.github.com> Date: Mon, 7 Jun 2021 13:32:13 +0100 Subject: [PATCH 12/15] Viewport Ui Cluster Locked State Overlay (#1139) * Viewport Ui Cluster Locked State Overlay * PR feedback changes. --- .../img/UI20/toolbar/Locked_Status.svg | 12 ++++ .../AzQtComponents/Components/resources.qrc | 3 +- .../EditorTransformComponentSelection.cpp | 3 + .../ViewportUi/ViewportUiCluster.cpp | 55 +++++++++++++++++++ .../ViewportUi/ViewportUiCluster.h | 4 ++ .../ViewportUi/ViewportUiDisplay.cpp | 8 +++ .../ViewportUi/ViewportUiDisplay.h | 1 + .../ViewportUi/ViewportUiManager.cpp | 10 ++++ .../ViewportUi/ViewportUiManager.h | 1 + .../ViewportUi/ViewportUiRequestBus.h | 2 + 10 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/toolbar/Locked_Status.svg diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/toolbar/Locked_Status.svg b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/toolbar/Locked_Status.svg new file mode 100644 index 0000000000..2612059dce --- /dev/null +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/toolbar/Locked_Status.svg @@ -0,0 +1,12 @@ + + + Icon / Locked Status + + + + + + + + + \ No newline at end of file diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc index 00fa95d094..7070bd372b 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc @@ -356,7 +356,8 @@ img/UI20/toolbar/Load.svg img/UI20/toolbar/Local.svg img/UI20/toolbar/Locked.svg - img/UI20/toolbar/LUA.svg + img/UI20/toolbar/Locked_Status.svg + img/UI20/toolbar/LUA.svg img/UI20/toolbar/Material.svg img/UI20/toolbar/Measure.svg img/UI20/toolbar/Move.svg diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp index db321d6818..5603c1a0f7 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp @@ -2646,6 +2646,9 @@ namespace AzToolsFramework m_spaceCluster.m_spaceLock = ReferenceFrame::World; } } + ViewportUi::ViewportUiRequestBus::Event( + ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::SetClusterButtonLocked, + m_spaceCluster.m_spaceClusterId, buttonId, m_spaceCluster.m_spaceLock.has_value()); }; m_spaceCluster.m_spaceSelectionHandler = AZ::Event::Handler(onButtonClicked); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.cpp index 79744f1dbf..d452d47508 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.cpp @@ -108,6 +108,61 @@ namespace AzToolsFramework::ViewportUi::Internal m_widgetCallbacks.Update(); } + void ViewportUiCluster::SetButtonLocked(const ButtonId buttonId, const bool isLocked) + { + const auto& buttons = m_buttonGroup->GetButtons(); + + // unlocked previously locked button + if (m_lockedButtonId.has_value() && isLocked) + { + // find the button to extract the old icon (without overlay) + auto findLocked = [this](const Button* button) { return (button->m_buttonId == m_lockedButtonId); }; + if (auto lockedButtonIt = AZStd::find_if(buttons.begin(), buttons.end(), findLocked); lockedButtonIt != buttons.end()) + { + // get the action corresponding to the lockedButtonId + if (auto actionEntry = m_buttonActionMap.find(m_lockedButtonId.value()); actionEntry != m_buttonActionMap.end()) + { + // remove the overlay + auto action = actionEntry->second; + action->setIcon(QIcon(QString((*lockedButtonIt)->m_icon.c_str()))); + } + } + } + + auto found = [buttonId](Button* button) { return (button->m_buttonId == buttonId); }; + if (auto buttonIt = AZStd::find_if(buttons.begin(), buttons.end(), found); buttonIt != buttons.end()) + { + QIcon newIcon; + + if (isLocked) + { + // overlay the locked icon ontop of the button's icon + QPixmap comboPixmap(24, 24); + comboPixmap.fill(Qt::transparent); + QPixmap firstImage(QString((*buttonIt)->m_icon.c_str())); + QPixmap secondImage(QString(":/stylesheet/img/UI20/toolbar/Locked_Status.svg")); + + QPainter painter(&comboPixmap); + painter.drawPixmap(0, 0, firstImage); + painter.drawPixmap(0, 0, secondImage); + newIcon.addPixmap(comboPixmap); + m_lockedButtonId = buttonId; + } + else + { + // remove the overlay + newIcon = QIcon(QString((*buttonIt)->m_icon.c_str())); + m_lockedButtonId = AZStd::nullopt; + } + + if (auto actionEntry = m_buttonActionMap.find(buttonId); actionEntry != m_buttonActionMap.end()) + { + auto action = actionEntry->second; + action->setIcon(newIcon); + } + } + } + ViewportUiWidgetCallbacks ViewportUiCluster::GetWidgetCallbacks() { return m_widgetCallbacks; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.h index 4f738177ea..027a201a9c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.h @@ -17,6 +17,7 @@ #include #include #include +#include namespace AzToolsFramework::ViewportUi::Internal { @@ -38,6 +39,8 @@ namespace AzToolsFramework::ViewportUi::Internal void RemoveButton(ButtonId buttonId); //! Updates all registered actions. void Update(); + //! Adds a locked overlay to the button's icon. + void SetButtonLocked(ButtonId buttonId, bool isLocked); //! Returns the widget manager. ViewportUiWidgetCallbacks GetWidgetCallbacks(); @@ -52,5 +55,6 @@ namespace AzToolsFramework::ViewportUi::Internal AZStd::shared_ptr m_buttonGroup; //!< Data structure which the cluster will be displaying to the Viewport UI. AZStd::unordered_map> m_buttonActionMap; //!< Map for buttons to their corresponding actions. ViewportUiWidgetCallbacks m_widgetCallbacks; //!< Registers actions and manages updates. + AZStd::optional m_lockedButtonId = AZStd::nullopt; //!< Used to track the last button locked. }; } // namespace AzToolsFramework::ViewportUi::Internal diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.cpp index e9e7dcc1cc..3565d33174 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.cpp @@ -100,6 +100,14 @@ namespace AzToolsFramework::ViewportUi::Internal } } + void ViewportUiDisplay::SetClusterButtonLocked(const ViewportUiElementId clusterId, const ButtonId buttonId, const bool isLocked) + { + if (auto viewportUiCluster = qobject_cast(GetViewportUiElement(clusterId).get())) + { + viewportUiCluster->SetButtonLocked(buttonId, isLocked); + } + } + void ViewportUiDisplay::RemoveClusterButton(ViewportUiElementId clusterId, ButtonId buttonId) { if (auto cluster = qobject_cast(GetViewportUiElement(clusterId).get())) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.h index d46e01c978..19d04e63ff 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.h @@ -58,6 +58,7 @@ namespace AzToolsFramework::ViewportUi::Internal void AddCluster(AZStd::shared_ptr buttonGroup, Alignment align); void AddClusterButton(ViewportUiElementId clusterId, Button* button); + void SetClusterButtonLocked(ViewportUiElementId clusterId, ButtonId buttonId, bool isLocked); void RemoveClusterButton(ViewportUiElementId clusterId, ButtonId buttonId); void UpdateCluster(const ViewportUiElementId clusterId); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.cpp index 12c3b5c9bb..0668af383b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.cpp @@ -67,6 +67,16 @@ namespace AzToolsFramework::ViewportUi } } + void ViewportUiManager::SetClusterButtonLocked(const ClusterId clusterId, const ButtonId buttonId, const bool isLocked) + { + if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end()) + { + auto cluster = clusterIt->second; + m_viewportUi->SetClusterButtonLocked(cluster->GetViewportUiElementId(), buttonId, isLocked); + UpdateButtonGroupUi(cluster.get()); + } + } + void ViewportUiManager::RegisterClusterEventHandler(const ClusterId clusterId, AZ::Event::Handler& handler) { if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end()) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.h index 04a58cef65..14609ccc14 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.h @@ -35,6 +35,7 @@ namespace AzToolsFramework::ViewportUi const SwitcherId CreateSwitcher(Alignment align) override; void SetClusterActiveButton(ClusterId clusterId, ButtonId buttonId) override; void SetSwitcherActiveButton(SwitcherId switcherId, ButtonId buttonId) override; + void SetClusterButtonLocked(ClusterId clusterId, ButtonId buttonId, bool isLocked) override; const ButtonId CreateClusterButton(ClusterId clusterId, const AZStd::string& icon) override; const ButtonId CreateSwitcherButton( SwitcherId switcherId, const AZStd::string& icon, const AZStd::string& name = AZStd::string()) override; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiRequestBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiRequestBus.h index 3879817ccb..a068ffe9ee 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiRequestBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiRequestBus.h @@ -65,6 +65,8 @@ namespace AzToolsFramework::ViewportUi virtual void SetClusterActiveButton(ClusterId clusterId, ButtonId buttonId) = 0; //! Sets the active button of the switcher. This is the button which has a text label. virtual void SetSwitcherActiveButton(SwitcherId clusterId, ButtonId buttonId) = 0; + //! Adds a locked overlay to the cluster button's icon. + virtual void SetClusterButtonLocked(ClusterId clusterId, ButtonId buttonId, bool isLocked) = 0; //! Registers a new button onto a cluster. virtual const ButtonId CreateClusterButton(const ClusterId clusterId, const AZStd::string& icon) = 0; //! Registers a new button onto a switcher. From c751cda73d0831e87beeca09832ff134219f8a25 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Mon, 7 Jun 2021 13:07:17 +0000 Subject: [PATCH 13/15] Fix for variable that is only used in the debug config (#1166) --- .../Code/Source/Integration/Components/ActorComponent.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.cpp b/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.cpp index f41ef165c8..b0065708fb 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.cpp @@ -299,8 +299,7 @@ namespace EMotionFX void ActorComponent::OnAssetReady(AZ::Data::Asset asset) { m_configuration.m_actorAsset = asset; - Actor* actor = m_configuration.m_actorAsset->GetActor(); - AZ_Assert(m_configuration.m_actorAsset.IsReady() && actor, "Actor asset should be loaded and actor valid."); + AZ_Assert(m_configuration.m_actorAsset.IsReady() && m_configuration.m_actorAsset->GetActor(), "Actor asset should be loaded and actor valid."); CheckActorCreation(); } From cf8a6761bf91a0e098643a54dbe2882ed3cc21de Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Mon, 7 Jun 2021 14:50:49 +0100 Subject: [PATCH 14/15] Formatting-only change - Update Manipulator and Viewport AzToolsFramework files (#1143) * formatting changes to AzToolsFramework viewport related types + API comment style updates * minor format change - include ordering * improve formatting by moving comment * fix compile error and switch to use AZ_Printf * small polish changes after review feedback --- Code/Framework/AzCore/AzCore/std/math.h | 3 + .../AzFramework/Viewport/CameraInput.cpp | 36 +- .../ActionDispatcher.h | 2 +- .../AzManipulatorTestFrameworkUtils.h | 9 +- .../ImmediateModeActionDispatcher.h | 10 +- .../AzManipulatorTestFrameworkUtils.cpp | 6 +- .../DirectManipulatorViewportInteraction.cpp | 42 +- .../Source/ImmediateModeActionDispatcher.cpp | 14 +- .../Tests/BusCallTest.cpp | 35 +- .../Tests/DirectCallTest.cpp | 21 +- .../Tests/GridSnappingTest.cpp | 5 +- .../Tests/ViewportInteractionTest.cpp | 6 +- .../Tests/WorldSpaceBuilderTest.cpp | 83 +- .../Manipulators/AngularManipulator.cpp | 96 +- .../Manipulators/AngularManipulator.h | 115 +- .../Manipulators/BaseManipulator.cpp | 125 +- .../Manipulators/BaseManipulator.h | 325 ++-- .../Manipulators/BoxManipulatorRequestBus.h | 49 +- .../Manipulators/EditorVertexSelection.cpp | 810 ++++---- .../Manipulators/EditorVertexSelection.h | 298 +-- .../Manipulators/HoverSelection.h | 64 +- .../Manipulators/LineHoverSelection.cpp | 53 +- .../Manipulators/LineHoverSelection.h | 35 +- .../LineSegmentSelectionManipulator.cpp | 50 +- .../LineSegmentSelectionManipulator.h | 71 +- .../Manipulators/LinearManipulator.cpp | 97 +- .../Manipulators/LinearManipulator.h | 132 +- .../Manipulators/ManipulatorBus.h | 79 +- .../Manipulators/ManipulatorManager.cpp | 67 +- .../Manipulators/ManipulatorManager.h | 83 +- .../Manipulators/ManipulatorSnapping.cpp | 106 +- .../Manipulators/ManipulatorSnapping.h | 118 +- .../Manipulators/ManipulatorSpace.h | 22 +- .../Manipulators/ManipulatorView.cpp | 449 ++--- .../Manipulators/ManipulatorView.h | 323 ++-- .../Manipulators/MultiLinearManipulator.cpp | 58 +- .../Manipulators/MultiLinearManipulator.h | 29 +- .../Manipulators/PlanarManipulator.cpp | 82 +- .../Manipulators/PlanarManipulator.h | 108 +- .../Manipulators/RotationManipulators.cpp | 57 +- .../Manipulators/RotationManipulators.h | 35 +- .../Manipulators/ScaleManipulators.cpp | 71 +- .../Manipulators/ScaleManipulators.h | 40 +- .../Manipulators/SelectionManipulator.cpp | 35 +- .../Manipulators/SelectionManipulator.h | 69 +- .../Manipulators/SplineHoverSelection.cpp | 37 +- .../Manipulators/SplineHoverSelection.h | 34 +- .../SplineSelectionManipulator.cpp | 45 +- .../Manipulators/SplineSelectionManipulator.h | 57 +- .../Manipulators/SurfaceManipulator.cpp | 84 +- .../Manipulators/SurfaceManipulator.h | 89 +- .../Manipulators/TranslationManipulators.cpp | 103 +- .../Manipulators/TranslationManipulators.h | 75 +- .../AzToolsFramework/Picking/BoundInterface.h | 87 +- .../Picking/ContextBoundAPI.h | 64 +- .../Manipulators/ManipulatorBoundManager.cpp | 41 +- .../Manipulators/ManipulatorBoundManager.h | 38 +- .../Manipulators/ManipulatorBounds.cpp | 64 +- .../Picking/Manipulators/ManipulatorBounds.h | 125 +- .../Viewport/EditorContextMenu.cpp | 41 +- .../Viewport/EditorContextMenu.h | 30 +- .../Viewport/VertexContainerDisplay.cpp | 39 +- .../Viewport/VertexContainerDisplay.h | 29 +- .../Viewport/ViewportMessages.h | 224 +-- .../Viewport/ViewportTypes.cpp | 62 +- .../AzToolsFramework/Viewport/ViewportTypes.h | 258 +-- .../EditorDefaultSelection.cpp | 163 +- .../EditorDefaultSelection.h | 95 +- .../ViewportSelection/EditorHelpers.cpp | 97 +- .../ViewportSelection/EditorHelpers.h | 54 +- .../EditorInteractionSystemComponent.cpp | 44 +- .../EditorInteractionSystemComponent.h | 50 +- ...ractionSystemViewportSelectionRequestBus.h | 60 +- .../EditorPickEntitySelection.cpp | 52 +- .../EditorPickEntitySelection.h | 40 +- .../ViewportSelection/EditorSelectionUtil.cpp | 92 +- .../ViewportSelection/EditorSelectionUtil.h | 65 +- .../EditorTransformComponentSelection.cpp | 1623 ++++++++--------- ...rTransformComponentSelectionRequestBus.cpp | 104 +- ...torTransformComponentSelectionRequestBus.h | 80 +- .../EditorVisibleEntityDataCache.cpp | 100 +- .../EditorVisibleEntityDataCache.h | 31 +- .../Tests/ComponentModeTests.cpp | 131 +- 83 files changed, 4438 insertions(+), 4492 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/std/math.h b/Code/Framework/AzCore/AzCore/std/math.h index 9e9be7944a..f5e2ac7ea7 100644 --- a/Code/Framework/AzCore/AzCore/std/math.h +++ b/Code/Framework/AzCore/AzCore/std/math.h @@ -21,11 +21,14 @@ namespace AZStd using std::asin; using std::atan; using std::atan2; + using std::ceil; using std::cos; using std::exp2; + using std::floor; using std::fmod; using std::round; using std::sin; using std::sqrt; using std::tan; + using std::trunc; } // namespace AZStd diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp index 559f7ce460..674e10812b 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp @@ -22,7 +22,11 @@ namespace AzFramework { AZ_CVAR( - float, ed_cameraSystemDefaultPlaneHeight, 34.0f, nullptr, AZ::ConsoleFunctorFlags::Null, + float, + ed_cameraSystemDefaultPlaneHeight, + 34.0f, + nullptr, + AZ::ConsoleFunctorFlags::Null, "The default height of the ground plane to do intersection tests against when orbiting"); AZ_CVAR(float, ed_cameraSystemBoostMultiplier, 3.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemTranslateSpeed, 10.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); @@ -41,7 +45,11 @@ namespace AzFramework AZ_CVAR( AZ::CVarFixedString, ed_cameraSystemTranslateForwardKey, "keyboard_key_alphanumeric_W", nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR( - AZ::CVarFixedString, ed_cameraSystemTranslateBackwardKey, "keyboard_key_alphanumeric_S", nullptr, AZ::ConsoleFunctorFlags::Null, + AZ::CVarFixedString, + ed_cameraSystemTranslateBackwardKey, + "keyboard_key_alphanumeric_S", + nullptr, + AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR( AZ::CVarFixedString, ed_cameraSystemTranslateLeftKey, "keyboard_key_alphanumeric_A", nullptr, AZ::ConsoleFunctorFlags::Null, ""); @@ -326,7 +334,9 @@ namespace AzFramework } Camera RotateCameraInput::StepCamera( - const Camera& targetCamera, const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta, + const Camera& targetCamera, + const ScreenVector& cursorDelta, + [[maybe_unused]] const float scrollDelta, [[maybe_unused]] const float deltaTime) { Camera nextCamera = targetCamera; @@ -374,7 +384,9 @@ namespace AzFramework } Camera PanCameraInput::StepCamera( - const Camera& targetCamera, const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta, + const Camera& targetCamera, + const ScreenVector& cursorDelta, + [[maybe_unused]] const float scrollDelta, [[maybe_unused]] const float deltaTime) { Camera nextCamera = targetCamera; @@ -473,7 +485,9 @@ namespace AzFramework } Camera TranslateCameraInput::StepCamera( - const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta, + const Camera& targetCamera, + [[maybe_unused]] const ScreenVector& cursorDelta, + [[maybe_unused]] const float scrollDelta, const float deltaTime) { Camera nextCamera = targetCamera; @@ -630,7 +644,9 @@ namespace AzFramework } Camera OrbitDollyScrollCameraInput::StepCamera( - const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, const float scrollDelta, + const Camera& targetCamera, + [[maybe_unused]] const ScreenVector& cursorDelta, + const float scrollDelta, [[maybe_unused]] const float deltaTime) { Camera nextCamera = targetCamera; @@ -666,7 +682,9 @@ namespace AzFramework } Camera OrbitDollyCursorMoveCameraInput::StepCamera( - const Camera& targetCamera, const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta, + const Camera& targetCamera, + const ScreenVector& cursorDelta, + [[maybe_unused]] const float scrollDelta, [[maybe_unused]] const float deltaTime) { Camera nextCamera = targetCamera; @@ -686,7 +704,9 @@ namespace AzFramework } Camera ScrollTranslationCameraInput::StepCamera( - const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, const float scrollDelta, + const Camera& targetCamera, + [[maybe_unused]] const ScreenVector& cursorDelta, + const float scrollDelta, [[maybe_unused]] const float deltaTime) { Camera nextCamera = targetCamera; diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ActionDispatcher.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ActionDispatcher.h index c9211e9f26..1eba4f3799 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ActionDispatcher.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ActionDispatcher.h @@ -97,7 +97,7 @@ namespace AzManipulatorTestFramework if (m_logging) { AZStd::string message = AZStd::string::format(format, args...); - std::cout << "[ActionDispatcher] " << message.c_str() << "\n"; + AZ_Printf("[ActionDispatcher] %s", message.c_str()); } } diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h index f1c32e4d8d..9d380003e2 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h @@ -21,12 +21,14 @@ namespace AzManipulatorTestFramework { //! Create a linear manipulator with a unit sphere bound. AZStd::shared_ptr CreateLinearManipulator( - const AzToolsFramework::ManipulatorManagerId manipulatorManagerId, const AZ::Vector3& position = AZ::Vector3::CreateZero(), + const AzToolsFramework::ManipulatorManagerId manipulatorManagerId, + const AZ::Vector3& position = AZ::Vector3::CreateZero(), float radius = 1.0f); //! Create a planar manipulator with a unit sphere bound. AZStd::shared_ptr CreatePlanarManipulator( - const AzToolsFramework::ManipulatorManagerId manipulatorManagerId, const AZ::Vector3& position = AZ::Vector3::CreateZero(), + const AzToolsFramework::ManipulatorManagerId manipulatorManagerId, + const AZ::Vector3& position = AZ::Vector3::CreateZero(), float radius = 1.0f); //! Create a mouse pick from the specified ray and screen point. @@ -39,7 +41,8 @@ namespace AzManipulatorTestFramework //! Create a mouse interaction from the specified pick, buttons, interaction id and keyboard modifiers. AzToolsFramework::ViewportInteraction::MouseInteraction CreateMouseInteraction( - const AzToolsFramework::ViewportInteraction::MousePick& mousePick, AzToolsFramework::ViewportInteraction::MouseButtons buttons, + const AzToolsFramework::ViewportInteraction::MousePick& mousePick, + AzToolsFramework::ViewportInteraction::MouseButtons buttons, AzToolsFramework::ViewportInteraction::InteractionId interactionId, AzToolsFramework::ViewportInteraction::KeyboardModifiers modifiers); diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ImmediateModeActionDispatcher.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ImmediateModeActionDispatcher.h index 6759c2255f..1faf4eff65 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ImmediateModeActionDispatcher.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ImmediateModeActionDispatcher.h @@ -12,14 +12,13 @@ #pragma once -#include #include +#include namespace AzManipulatorTestFramework { //! Dispatches actions immediately to the manipulators. - class ImmediateModeActionDispatcher - : public ActionDispatcher + class ImmediateModeActionDispatcher : public ActionDispatcher { using KeyboardModifier = AzToolsFramework::ViewportInteraction::KeyboardModifier; using KeyboardModifiers = AzToolsFramework::ViewportInteraction::KeyboardModifiers; @@ -62,7 +61,7 @@ namespace AzManipulatorTestFramework void MouseLButtonUpImpl() override; void MousePositionImpl(const AzFramework::ScreenPoint& position) override; void KeyboardModifierDownImpl(const KeyboardModifier& keyModifier) override; - void KeyboardModifierUpImpl(const KeyboardModifier& keyModifier) override; + void KeyboardModifierUpImpl(const KeyboardModifier& keyModifier) override; void ExpectManipulatorBeingInteractedImpl() override; void ExpectManipulatorNotBeingInteractedImpl() override; void SetEntityWorldTransformImpl(AZ::EntityId entityId, const AZ::Transform& transform) override; @@ -97,8 +96,7 @@ namespace AzManipulatorTestFramework return this; } - inline ImmediateModeActionDispatcher* ImmediateModeActionDispatcher::GetKeyboardModifiers( - KeyboardModifiers& keyboardModifiers) + inline ImmediateModeActionDispatcher* ImmediateModeActionDispatcher::GetKeyboardModifiers(KeyboardModifiers& keyboardModifiers) { keyboardModifiers = GetKeyboardModifiers(); return this; diff --git a/Code/Framework/AzManipulatorTestFramework/Source/AzManipulatorTestFrameworkUtils.cpp b/Code/Framework/AzManipulatorTestFramework/Source/AzManipulatorTestFrameworkUtils.cpp index 985c21cf8e..83746c9490 100644 --- a/Code/Framework/AzManipulatorTestFramework/Source/AzManipulatorTestFrameworkUtils.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Source/AzManipulatorTestFrameworkUtils.cpp @@ -30,8 +30,10 @@ namespace AzManipulatorTestFramework // create a default sphere view for a manipulator for simple intersection template void SetupManipulatorView( - AZStd::shared_ptr manipulator, const AzToolsFramework::ManipulatorManagerId manipulatorManagerId, - const AZ::Vector3& position, const float radius) + AZStd::shared_ptr manipulator, + const AzToolsFramework::ManipulatorManagerId manipulatorManagerId, + const AZ::Vector3& position, + const float radius) { // unit sphere view auto sphereView = AzToolsFramework::CreateManipulatorViewSphere( diff --git a/Code/Framework/AzManipulatorTestFramework/Source/DirectManipulatorViewportInteraction.cpp b/Code/Framework/AzManipulatorTestFramework/Source/DirectManipulatorViewportInteraction.cpp index 5c5f77629c..192202cee2 100644 --- a/Code/Framework/AzManipulatorTestFramework/Source/DirectManipulatorViewportInteraction.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Source/DirectManipulatorViewportInteraction.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include #include @@ -19,10 +19,10 @@ namespace AzManipulatorTestFramework using MouseInteraction = AzToolsFramework::ViewportInteraction::MouseInteraction; using MouseInteractionEvent = AzToolsFramework::ViewportInteraction::MouseInteractionEvent; - class CustomManipulatorManager - : public AzToolsFramework::ManipulatorManager + class CustomManipulatorManager : public AzToolsFramework::ManipulatorManager { using ManagerBase = AzToolsFramework::ManipulatorManager; + public: using ManagerBase::ManagerBase; @@ -31,18 +31,17 @@ namespace AzManipulatorTestFramework }; //! Implementation of the manipulator interface using direct access to the manipulator manager. - class DirectCallManipulatorManager - : public ManipulatorManagerInterface + class DirectCallManipulatorManager : public ManipulatorManagerInterface { public: DirectCallManipulatorManager( - ViewportInteractionInterface* viewportInteraction, - AZStd::shared_ptr manipulatorManager); - + ViewportInteractionInterface* viewportInteraction, AZStd::shared_ptr manipulatorManager); + // ManipulatorManagerInterface ... void ConsumeMouseInteractionEvent(const MouseInteractionEvent& event); AzToolsFramework::ManipulatorManagerId GetId() const override; bool ManipulatorBeingInteracted() const override; + private: // Trigger the updating of manipulator bounds. void DrawManipulators(const MouseInteraction& mouseInteraction); @@ -61,8 +60,7 @@ namespace AzManipulatorTestFramework } DirectCallManipulatorManager::DirectCallManipulatorManager( - ViewportInteractionInterface* viewportInteraction, - AZStd::shared_ptr manipulatorManager) + ViewportInteractionInterface* viewportInteraction, AZStd::shared_ptr manipulatorManager) : m_viewportInteraction(viewportInteraction) , m_manipulatorManager(AZStd::move(manipulatorManager)) { @@ -126,11 +124,9 @@ namespace AzManipulatorTestFramework DirectCallManipulatorViewportInteraction::DirectCallManipulatorViewportInteraction() : m_customManager( - AZStd::make_unique( - AzToolsFramework::ManipulatorManagerId(AZ::Crc32("TestManipulatorManagerId")))) + AZStd::make_unique(AzToolsFramework::ManipulatorManagerId(AZ::Crc32("TestManipulatorManagerId")))) , m_viewportInteraction(AZStd::make_unique()) - , m_manipulatorManager( - AZStd::make_unique(m_viewportInteraction.get(), m_customManager)) + , m_manipulatorManager(AZStd::make_unique(m_viewportInteraction.get(), m_customManager)) { } diff --git a/Code/Framework/AzManipulatorTestFramework/Source/ImmediateModeActionDispatcher.cpp b/Code/Framework/AzManipulatorTestFramework/Source/ImmediateModeActionDispatcher.cpp index ad59d9578a..356a146125 100644 --- a/Code/Framework/AzManipulatorTestFramework/Source/ImmediateModeActionDispatcher.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Source/ImmediateModeActionDispatcher.cpp @@ -10,8 +10,8 @@ * */ -#include #include +#include #include #include @@ -33,8 +33,7 @@ namespace AzManipulatorTestFramework using KeyboardModifier = AzToolsFramework::ViewportInteraction::KeyboardModifier; using MouseInteractionEvent = AzToolsFramework::ViewportInteraction::MouseInteractionEvent; - ImmediateModeActionDispatcher::ImmediateModeActionDispatcher( - ManipulatorViewportInteraction& viewportManipulatorInteraction) + ImmediateModeActionDispatcher::ImmediateModeActionDispatcher(ManipulatorViewportInteraction& viewportManipulatorInteraction) : m_viewportManipulatorInteraction(viewportManipulatorInteraction) { } @@ -126,8 +125,7 @@ namespace AzManipulatorTestFramework void ImmediateModeActionDispatcher::EnterComponentModeImpl(const AZ::Uuid& uuid) { using AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus; - ComponentModeSystemRequestBus::Broadcast( - &ComponentModeSystemRequestBus::Events::AddSelectedComponentModesOfType, uuid); + ComponentModeSystemRequestBus::Broadcast(&ComponentModeSystemRequestBus::Events::AddSelectedComponentModesOfType, uuid); } const AzToolsFramework::ViewportInteraction::MouseInteractionEvent* ImmediateModeActionDispatcher::GetMouseInteractionEvent() const @@ -144,8 +142,7 @@ namespace AzManipulatorTestFramework AzToolsFramework::ViewportInteraction::MouseInteractionEvent* ImmediateModeActionDispatcher::GetMouseInteractionEvent() { - return const_cast( - static_cast(this)->GetMouseInteractionEvent()); + return const_cast(static_cast(this)->GetMouseInteractionEvent()); } ImmediateModeActionDispatcher* ImmediateModeActionDispatcher::ExpectTrue(bool result) @@ -162,8 +159,7 @@ namespace AzManipulatorTestFramework return this; } - ImmediateModeActionDispatcher* ImmediateModeActionDispatcher::GetEntityWorldTransform( - AZ::EntityId entityId, AZ::Transform& transform) + ImmediateModeActionDispatcher* ImmediateModeActionDispatcher::GetEntityWorldTransform(AZ::EntityId entityId, AZ::Transform& transform) { Log("Getting entity world transform"); transform = AzToolsFramework::GetWorldTransform(entityId); diff --git a/Code/Framework/AzManipulatorTestFramework/Tests/BusCallTest.cpp b/Code/Framework/AzManipulatorTestFramework/Tests/BusCallTest.cpp index 8cc906f339..b2da9965e6 100644 --- a/Code/Framework/AzManipulatorTestFramework/Tests/BusCallTest.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Tests/BusCallTest.cpp @@ -11,17 +11,18 @@ */ #include "AzManipulatorTestFrameworkTestFixtures.h" -#include #include +#include namespace UnitTest { - class AzManipulatorTestFrameworkBusCallTestFixture - : public LinearManipulatorTestFixture + class AzManipulatorTestFrameworkBusCallTestFixture : public LinearManipulatorTestFixture { protected: AzManipulatorTestFrameworkBusCallTestFixture() - : LinearManipulatorTestFixture(AzToolsFramework::g_mainManipulatorManagerId) {} + : LinearManipulatorTestFixture(AzToolsFramework::g_mainManipulatorManagerId) + { + } bool IsManipulatorInteractingBusCall() const { @@ -37,8 +38,8 @@ namespace UnitTest TEST_F(AzManipulatorTestFrameworkBusCallTestFixture, ConsumeViewportLeftMouseClick) { // given a left mouse down ray in world space - auto event = AzManipulatorTestFramework::CreateMouseInteractionEvent( - m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down); + auto event = + AzManipulatorTestFramework::CreateMouseInteractionEvent(m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down); // consume the mouse down and up events AzManipulatorTestFramework::DispatchMouseInteractionEvent(event); @@ -56,8 +57,8 @@ namespace UnitTest TEST_F(AzManipulatorTestFrameworkBusCallTestFixture, ConsumeViewportMouseMoveHover) { // given a left mouse down ray in world space - const auto event = AzManipulatorTestFramework::CreateMouseInteractionEvent( - m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Move); + const auto event = + AzManipulatorTestFramework::CreateMouseInteractionEvent(m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Move); // consume the mouse move event AzManipulatorTestFramework::DispatchMouseInteractionEvent(event); @@ -75,8 +76,8 @@ namespace UnitTest TEST_F(AzManipulatorTestFrameworkBusCallTestFixture, ConsumeViewportMouseMoveActive) { // given a left mouse down ray in world space - auto event = AzManipulatorTestFramework::CreateMouseInteractionEvent( - m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down); + auto event = + AzManipulatorTestFramework::CreateMouseInteractionEvent(m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down); // consume the mouse down event AzManipulatorTestFramework::DispatchMouseInteractionEvent(event); @@ -110,14 +111,14 @@ namespace UnitTest const AZ::Vector3 initialManipulatorPosition = m_linearManipulator->GetLocalPosition(); m_linearManipulator->InstallMouseMoveCallback( [&movementAlongAxis, this](const AzToolsFramework::LinearManipulator::Action& action) - { - movementAlongAxis = action.LocalPositionOffset(); - m_linearManipulator->SetLocalPosition(action.LocalPosition()); - }); + { + movementAlongAxis = action.LocalPositionOffset(); + m_linearManipulator->SetLocalPosition(action.LocalPosition()); + }); // given a left mouse down ray in world space - auto event = AzManipulatorTestFramework::CreateMouseInteractionEvent( - m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down); + auto event = + AzManipulatorTestFramework::CreateMouseInteractionEvent(m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down); // consume the mouse down event AzManipulatorTestFramework::DispatchMouseInteractionEvent(event); @@ -134,7 +135,7 @@ namespace UnitTest // consume the mouse up event event.m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Up; AzManipulatorTestFramework::DispatchMouseInteractionEvent(event); - + // expect the left mouse down/up sanity flags to be set EXPECT_TRUE(m_receivedLeftMouseDown); EXPECT_TRUE(m_receivedLeftMouseUp); diff --git a/Code/Framework/AzManipulatorTestFramework/Tests/DirectCallTest.cpp b/Code/Framework/AzManipulatorTestFramework/Tests/DirectCallTest.cpp index bec61ce9a8..af810c1dcf 100644 --- a/Code/Framework/AzManipulatorTestFramework/Tests/DirectCallTest.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Tests/DirectCallTest.cpp @@ -14,10 +14,10 @@ namespace UnitTest { - class CustomManipulatorManager - : public AzToolsFramework::ManipulatorManager + class CustomManipulatorManager : public AzToolsFramework::ManipulatorManager { using ManagerBase = AzToolsFramework::ManipulatorManager; + public: using ManagerBase::ManagerBase; @@ -27,17 +27,17 @@ namespace UnitTest } }; - class AzManipulatorTestFrameworkCustomManagerTestFixture - : public LinearManipulatorTestFixture + class AzManipulatorTestFrameworkCustomManagerTestFixture : public LinearManipulatorTestFixture { protected: AzManipulatorTestFrameworkCustomManagerTestFixture() - : LinearManipulatorTestFixture(AzToolsFramework::ManipulatorManagerId(AZ::Crc32("TestManipulatorManagerId"))) {} + : LinearManipulatorTestFixture(AzToolsFramework::ManipulatorManagerId(AZ::Crc32("TestManipulatorManagerId"))) + { + } void SetUpEditorFixtureImpl() override { - m_manipulatorManager = - AZStd::make_shared(m_manipulatorManagerId); + m_manipulatorManager = AZStd::make_shared(m_manipulatorManagerId); LinearManipulatorTestFixture::SetUpEditorFixtureImpl(); } @@ -115,9 +115,9 @@ namespace UnitTest m_linearManipulator->InstallMouseMoveCallback( [&movementAlongAxis](const AzToolsFramework::LinearManipulator::Action& action) - { - movementAlongAxis = action.m_current.m_localPositionOffset; - }); + { + movementAlongAxis = action.m_current.m_localPositionOffset; + }); // consume the mouse down event m_manipulatorManager->ConsumeViewportMousePress(m_interaction); @@ -141,4 +141,3 @@ namespace UnitTest EXPECT_EQ(movementAlongAxis, expectedPositionAfterMovementAlongAxis); } } // namespace UnitTest - diff --git a/Code/Framework/AzManipulatorTestFramework/Tests/GridSnappingTest.cpp b/Code/Framework/AzManipulatorTestFramework/Tests/GridSnappingTest.cpp index d6006ba74f..160a9933d9 100644 --- a/Code/Framework/AzManipulatorTestFramework/Tests/GridSnappingTest.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Tests/GridSnappingTest.cpp @@ -12,6 +12,7 @@ #include "AzManipulatorTestFrameworkTestFixtures.h" +#include #include #include #include @@ -22,7 +23,6 @@ #include #include #include -#include namespace UnitTest { @@ -94,7 +94,8 @@ namespace UnitTest template void ValidateManipulatorSnappingBehavior( - AZStd::shared_ptr manipulator, AzManipulatorTestFramework::ImmediateModeActionDispatcher* actionDispatcher, + AZStd::shared_ptr manipulator, + AzManipulatorTestFramework::ImmediateModeActionDispatcher* actionDispatcher, const AzFramework::CameraState& cameraState) { manipulator->SetLocalOrientation(AZ::Quaternion::CreateFromEulerAnglesDegrees(AZ::Vector3(180.0f, 0.0f, 135.0f))); diff --git a/Code/Framework/AzManipulatorTestFramework/Tests/ViewportInteractionTest.cpp b/Code/Framework/AzManipulatorTestFramework/Tests/ViewportInteractionTest.cpp index 6ba44cc71b..4aad2ea138 100644 --- a/Code/Framework/AzManipulatorTestFramework/Tests/ViewportInteractionTest.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Tests/ViewportInteractionTest.cpp @@ -15,8 +15,7 @@ namespace UnitTest { - class AValidViewportInteraction - : public ToolsApplicationFixture + class AValidViewportInteraction : public ToolsApplicationFixture { public: AValidViewportInteraction() @@ -27,8 +26,7 @@ namespace UnitTest protected: void SetUpEditorFixtureImpl() override { - m_cameraState = - AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AZ::Vector2(800.0f, 600.0f)); + m_cameraState = AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AZ::Vector2(800.0f, 600.0f)); } public: diff --git a/Code/Framework/AzManipulatorTestFramework/Tests/WorldSpaceBuilderTest.cpp b/Code/Framework/AzManipulatorTestFramework/Tests/WorldSpaceBuilderTest.cpp index a6c58971f6..6168e9cece 100644 --- a/Code/Framework/AzManipulatorTestFramework/Tests/WorldSpaceBuilderTest.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Tests/WorldSpaceBuilderTest.cpp @@ -11,49 +11,48 @@ */ #include -#include #include +#include #include -#include #include -#include +#include #include +#include namespace UnitTest { - class AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture - : public ToolsApplicationFixture + class AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture : public ToolsApplicationFixture { protected: struct State { State(AZStd::unique_ptr viewportManipulatorInteraction) : m_viewportManipulatorInteraction(viewportManipulatorInteraction.release()) - , m_actionDispatcher(AZStd::make_unique(*m_viewportManipulatorInteraction)) - , m_linearManipulator( - AzManipulatorTestFramework::CreateLinearManipulator( - m_viewportManipulatorInteraction->GetManipulatorManager().GetId(), - /*position=*/AZ::Vector3(0.0f, 50.0f, 0.0f), - /*radius=*/m_boundsRadius)) + , m_actionDispatcher( + AZStd::make_unique(*m_viewportManipulatorInteraction)) + , m_linearManipulator(AzManipulatorTestFramework::CreateLinearManipulator( + m_viewportManipulatorInteraction->GetManipulatorManager().GetId(), + /*position=*/AZ::Vector3(0.0f, 50.0f, 0.0f), + /*radius=*/m_boundsRadius)) { // default sanity check call backs m_linearManipulator->InstallLeftMouseDownCallback( [this]([[maybe_unused]] const AzToolsFramework::LinearManipulator::Action& action) - { - m_receivedLeftMouseDown = true; - }); + { + m_receivedLeftMouseDown = true; + }); m_linearManipulator->InstallMouseMoveCallback( [this]([[maybe_unused]] const AzToolsFramework::LinearManipulator::Action& action) - { - m_receivedMouseMove = true; - }); + { + m_receivedMouseMove = true; + }); m_linearManipulator->InstallLeftMouseUpCallback( [this]([[maybe_unused]] const AzToolsFramework::LinearManipulator::Action& action) - { - m_receivedLeftMouseUp = true; - }); + { + m_receivedLeftMouseUp = true; + }); } ~State() = default; @@ -79,13 +78,12 @@ namespace UnitTest protected: void SetUpEditorFixtureImpl() override { - m_directState = AZStd::make_unique( - AZStd::make_unique()); - m_busState = AZStd::make_unique( - AZStd::make_unique()); + m_directState = + AZStd::make_unique(AZStd::make_unique()); + m_busState = + AZStd::make_unique(AZStd::make_unique()); m_cameraState = - AzFramework::CreateIdentityDefaultCamera( - AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize); + AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize); } void TearDownEditorFixtureImpl() override @@ -105,8 +103,7 @@ namespace UnitTest { // given a left mouse down ray in world space // consume the mouse down and up events - state.m_actionDispatcher - ->CameraState(m_cameraState) + state.m_actionDispatcher->CameraState(m_cameraState) ->MousePosition(AzManipulatorTestFramework::GetCameraStateViewportCenter(m_cameraState)) ->MouseLButtonDown() ->Trace("Expecting left mouse button down") @@ -126,31 +123,27 @@ namespace UnitTest ->ExpectTrue(state.m_receivedLeftMouseUp) ->ExpectTrue(state.m_receivedMouseMove) ->ExpectFalse(state.m_linearManipulator->PerformingAction()) - ->ExpectManipulatorNotBeingInteracted() - ; + ->ExpectManipulatorNotBeingInteracted(); } void AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture::ConsumeViewportMouseMoveHover(State& state) { // given a left mouse down ray in world space // consume the mouse move event - state.m_actionDispatcher - ->CameraState(m_cameraState) + state.m_actionDispatcher->CameraState(m_cameraState) ->MousePosition(AzManipulatorTestFramework::GetCameraStateViewportCenter(m_cameraState)) ->ExpectFalse(state.m_linearManipulator->PerformingAction()) ->ExpectManipulatorNotBeingInteracted() ->ExpectFalse(state.m_receivedLeftMouseDown) ->ExpectFalse(state.m_receivedMouseMove) - ->ExpectFalse(state.m_receivedLeftMouseUp) - ; + ->ExpectFalse(state.m_receivedLeftMouseUp); } void AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture::ConsumeViewportMouseMoveActive(State& state) { // given a left mouse down ray in world space // consume the mouse move event - state.m_actionDispatcher - ->CameraState(m_cameraState) + state.m_actionDispatcher->CameraState(m_cameraState) ->MouseLButtonDown() ->MousePosition(AzManipulatorTestFramework::GetCameraStateViewportCenter(m_cameraState)) ->ExpectTrue(state.m_linearManipulator->PerformingAction()) @@ -158,8 +151,7 @@ namespace UnitTest ->MouseLButtonUp() ->ExpectTrue(state.m_receivedLeftMouseDown) ->ExpectTrue(state.m_receivedMouseMove) - ->ExpectTrue(state.m_receivedLeftMouseUp) - ; + ->ExpectTrue(state.m_receivedLeftMouseUp); } void AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture::MoveManipulatorAlongAxis(State& state) @@ -176,8 +168,7 @@ namespace UnitTest // adjusted final world position taking into account the manipulator position relative to the camera const auto finalPositionWorldAdjusted = finalPositionWorld - (vectorToInitialPositionWorld * scaledRadiusBound); // calculate the position in screen space of the initial position of the manipulator - const auto initialPositionScreen = - AzFramework::WorldToScreen(initialPositionWorld, m_cameraState); + const auto initialPositionScreen = AzFramework::WorldToScreen(initialPositionWorld, m_cameraState); // calculate the position in screen space of the final position of the manipulator const auto finalPositionScreen = AzFramework::WorldToScreen(finalPositionWorldAdjusted, m_cameraState); @@ -185,12 +176,11 @@ namespace UnitTest state.m_linearManipulator->InstallMouseMoveCallback( [&movementAlongAxis](const AzToolsFramework::LinearManipulator::Action& action) - { - movementAlongAxis = action.LocalPosition(); - }); + { + movementAlongAxis = action.LocalPosition(); + }); - state.m_actionDispatcher - ->CameraState(m_cameraState) + state.m_actionDispatcher->CameraState(m_cameraState) ->MousePosition(initialPositionScreen) ->MouseLButtonDown() ->ExpectTrue(state.m_linearManipulator->PerformingAction()) @@ -199,8 +189,7 @@ namespace UnitTest ->MouseLButtonUp() ->ExpectTrue(state.m_receivedLeftMouseDown) ->ExpectTrue(state.m_receivedLeftMouseUp) - ->ExpectTrue(movementAlongAxis.IsClose(finalPositionWorld, 0.01f)) - ; + ->ExpectTrue(movementAlongAxis.IsClose(finalPositionWorld, 0.01f)); } TEST_F(AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture, ConsumeViewportLeftMouseClick) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/AngularManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/AngularManipulator.cpp index 9a4a952d8f..6141fd9642 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/AngularManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/AngularManipulator.cpp @@ -1,28 +1,32 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "AngularManipulator.h" #include -#include #include +#include namespace AzToolsFramework { - static const float s_circularRotateThresholdDegrees = 80.0f; + static const float CircularRotateThresholdDegrees = 80.0f; AngularManipulator::ActionInternal AngularManipulator::CalculateManipulationDataStart( - const Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Transform& localTransform, - const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, const float rayDistance) + const Fixed& fixed, + const AZ::Transform& worldFromLocal, + const AZ::Transform& localTransform, + const AZ::Vector3& rayOrigin, + const AZ::Vector3& rayDirection, + const float rayDistance) { const AZ::Transform worldFromLocalWithTransform = worldFromLocal * localTransform; const AZ::Vector3 worldAxis = TransformDirectionNoScaling(worldFromLocalWithTransform, fixed.m_axis); @@ -35,7 +39,7 @@ namespace AzToolsFramework // if angular manipulator axis is at right angles to us, use initial ray direction // as plane normal and use hit position on manipulator as plane point const float pickAngle = AZ::RadToDeg(AZ::Acos(AZ::Abs(rayDirection.Dot(worldAxis)))); - if (pickAngle > s_circularRotateThresholdDegrees) + if (pickAngle > CircularRotateThresholdDegrees) { actionInternal.m_start.m_planeNormal = -rayDirection; actionInternal.m_start.m_planePoint = rayOrigin + rayDirection * rayDistance; @@ -43,8 +47,8 @@ namespace AzToolsFramework // store initial world hit position Internal::CalculateRayPlaneIntersectingPoint( - rayOrigin, rayDirection, actionInternal.m_start.m_planePoint, - actionInternal.m_start.m_planeNormal, actionInternal.m_current.m_worldHitPosition); + rayOrigin, rayDirection, actionInternal.m_start.m_planePoint, actionInternal.m_start.m_planeNormal, + actionInternal.m_current.m_worldHitPosition); // store entity transform (to go from local to world space) // and store our own starting local transform @@ -56,31 +60,33 @@ namespace AzToolsFramework } AngularManipulator::Action AngularManipulator::CalculateManipulationDataAction( - const Fixed& fixed, ActionInternal& actionInternal, const AZ::Transform& worldFromLocal, - const AZ::Transform& localTransform, const bool snapping, const float angleStepDegrees, - const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, + const Fixed& fixed, + ActionInternal& actionInternal, + const AZ::Transform& worldFromLocal, + const AZ::Transform& localTransform, + const bool snapping, + const float angleStepDegrees, + const AZ::Vector3& rayOrigin, + const AZ::Vector3& rayDirection, const ViewportInteraction::KeyboardModifiers keyboardModifiers) { const AZ::Transform worldFromLocalWithTransform = worldFromLocal * localTransform; const AZ::Vector3 worldAxis = TransformDirectionNoScaling(worldFromLocalWithTransform, fixed.m_axis); AZ::Vector3 worldHitPosition = AZ::Vector3::CreateZero(); - Internal::CalculateRayPlaneIntersectingPoint(rayOrigin, rayDirection, - actionInternal.m_start.m_planePoint, actionInternal.m_start.m_planeNormal, - worldHitPosition); + Internal::CalculateRayPlaneIntersectingPoint( + rayOrigin, rayDirection, actionInternal.m_start.m_planePoint, actionInternal.m_start.m_planeNormal, worldHitPosition); // get vector from center of rotation for current and previous frame const AZ::Vector3 center = worldFromLocalWithTransform.GetTranslation(); const AZ::Vector3 currentWorldHitVector = (worldHitPosition - center).GetNormalizedSafe(); - const AZ::Vector3 previousWorldHitVector = - (actionInternal.m_current.m_worldHitPosition - center).GetNormalizedSafe(); + const AZ::Vector3 previousWorldHitVector = (actionInternal.m_current.m_worldHitPosition - center).GetNormalizedSafe(); // calculate which direction we rotated const AZ::Vector3 worldAxisRight = worldAxis.Cross(previousWorldHitVector); const float rotateSign = Sign(currentWorldHitVector.Dot(worldAxisRight)); // how far did we rotate this frame - const float rotationAngleRad = AZ::Acos(AZ::GetMin( - 1.0f, currentWorldHitVector.Dot(previousWorldHitVector))); + const float rotationAngleRad = AZ::Acos(AZ::GetMin(1.0f, currentWorldHitVector.Dot(previousWorldHitVector))); actionInternal.m_current.m_worldHitPosition = worldHitPosition; // if we're snapping, only increment current radians when we know @@ -148,16 +154,13 @@ namespace AzToolsFramework // calculate initial state when mouse press first happens m_actionInternal = CalculateManipulationDataStart( m_fixed, TransformNormalizedScale(GetSpace()), TransformNormalizedScale(GetLocalTransform()), - interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, - rayIntersectionDistance); + interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, rayIntersectionDistance); if (m_onLeftMouseDownCallback) { m_onLeftMouseDownCallback(CalculateManipulationDataAction( - m_fixed, m_actionInternal, m_actionInternal.m_start.m_worldFromLocal, - m_actionInternal.m_start.m_localTransform, snapping, angleStep, - interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, - interaction.m_keyboardModifiers)); + m_fixed, m_actionInternal, m_actionInternal.m_start.m_worldFromLocal, m_actionInternal.m_start.m_localTransform, snapping, + angleStep, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, interaction.m_keyboardModifiers)); } } @@ -167,12 +170,9 @@ namespace AzToolsFramework { // calculate delta rotation m_onMouseMoveCallback(CalculateManipulationDataAction( - m_fixed, m_actionInternal, m_actionInternal.m_start.m_worldFromLocal, - m_actionInternal.m_start.m_localTransform, - AngleSnapping(interaction.m_interactionId.m_viewportId), - AngleStep(interaction.m_interactionId.m_viewportId), - interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, - interaction.m_keyboardModifiers)); + m_fixed, m_actionInternal, m_actionInternal.m_start.m_worldFromLocal, m_actionInternal.m_start.m_localTransform, + AngleSnapping(interaction.m_interactionId.m_viewportId), AngleStep(interaction.m_interactionId.m_viewportId), + interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, interaction.m_keyboardModifiers)); } } @@ -181,12 +181,9 @@ namespace AzToolsFramework if (m_onLeftMouseUpCallback) { m_onLeftMouseUpCallback(CalculateManipulationDataAction( - m_fixed, m_actionInternal, m_actionInternal.m_start.m_worldFromLocal, - m_actionInternal.m_start.m_localTransform, - AngleSnapping(interaction.m_interactionId.m_viewportId), - AngleStep(interaction.m_interactionId.m_viewportId), - interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, - interaction.m_keyboardModifiers)); + m_fixed, m_actionInternal, m_actionInternal.m_start.m_worldFromLocal, m_actionInternal.m_start.m_localTransform, + AngleSnapping(interaction.m_interactionId.m_viewportId), AngleStep(interaction.m_interactionId.m_viewportId), + interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, interaction.m_keyboardModifiers)); } } @@ -197,12 +194,9 @@ namespace AzToolsFramework const ViewportInteraction::MouseInteraction& mouseInteraction) { m_manipulatorView->Draw( - GetManipulatorManagerId(), managerState, - GetManipulatorId(), { - ApplySpace(GetLocalTransform()), GetNonUniformScale(), - AZ::Vector3::CreateZero(), MouseOver() - }, - debugDisplay, cameraState, mouseInteraction); + GetManipulatorManagerId(), managerState, GetManipulatorId(), + { ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, cameraState, + mouseInteraction); } void AngularManipulator::SetAxis(const AZ::Vector3& axis) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/AngularManipulator.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/AngularManipulator.h index e2f95fce5e..8e0468aa90 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/AngularManipulator.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/AngularManipulator.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -22,14 +22,14 @@ namespace AzToolsFramework { class ManipulatorView; - /// AngularManipulator serves as a visual tool for users to change a component's property based on rotation - /// around an axis. The rotation angle increases if the rotation goes counter clock-wise when looking - /// in the opposite direction the rotation axis points to. + //! AngularManipulator serves as a visual tool for users to change a component's property based on rotation + //! around an axis. The rotation angle increases if the rotation goes counter clock-wise when looking + //! in the opposite direction the rotation axis points to. class AngularManipulator : public BaseManipulator , public ManipulatorSpaceWithLocalTransform { - /// Private constructor. + //! Private constructor. explicit AngularManipulator(const AZ::Transform& worldFromLocal); public: @@ -42,33 +42,36 @@ namespace AzToolsFramework ~AngularManipulator() = default; - /// A Manipulator must only be created and managed through a shared_ptr. + //! A Manipulator must only be created and managed through a shared_ptr. static AZStd::shared_ptr MakeShared(const AZ::Transform& worldFromLocal); - /// The state of the manipulator at the start of an interaction. + //! The state of the manipulator at the start of an interaction. struct Start { - AZ::Quaternion m_space; ///< Starting orientation space of manipulator. - AZ::Quaternion m_rotation; ///< Starting local rotation of the manipulator. + AZ::Quaternion m_space; //!< Starting orientation space of manipulator. + AZ::Quaternion m_rotation; //!< Starting local rotation of the manipulator. }; - /// The state of the manipulator during an interaction. + //! The state of the manipulator during an interaction. struct Current { - AZ::Quaternion m_delta; ///< Amount of rotation to apply to manipulator during action. + AZ::Quaternion m_delta; //!< Amount of rotation to apply to manipulator during action. }; - /// Mouse action data used by MouseActionCallback (wraps Start and Current manipulator state). + //! Mouse action data used by MouseActionCallback (wraps Start and Current manipulator state). struct Action { Start m_start; Current m_current; ViewportInteraction::KeyboardModifiers m_modifiers; - AZ::Quaternion LocalOrientation() const { return m_start.m_rotation * m_current.m_delta; } + AZ::Quaternion LocalOrientation() const + { + return m_start.m_rotation * m_current.m_delta; + } }; - /// This is the function signature of callbacks that will be invoked whenever a manipulator - /// is clicked on or dragged. + //! This is the function signature of callbacks that will be invoked whenever a manipulator + //! is clicked on or dragged. using MouseActionCallback = AZStd::function; void InstallLeftMouseDownCallback(const MouseActionCallback& onMouseDownCallback); @@ -82,46 +85,49 @@ namespace AzToolsFramework const ViewportInteraction::MouseInteraction& mouseInteraction) override; void SetAxis(const AZ::Vector3& axis); - const AZ::Vector3& GetAxis() const { return m_fixed.m_axis; } + const AZ::Vector3& GetAxis() const + { + return m_fixed.m_axis; + } void SetView(AZStd::unique_ptr&& view); - ManipulatorView* GetView() const { return m_manipulatorView.get(); } + ManipulatorView* GetView() const + { + return m_manipulatorView.get(); + } private: - void OnLeftMouseDownImpl( - const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; - void OnLeftMouseUpImpl( - const ViewportInteraction::MouseInteraction& interaction) override; - void OnMouseMoveImpl( - const ViewportInteraction::MouseInteraction& interaction) override; + void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; + void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override; + void OnMouseMoveImpl(const ViewportInteraction::MouseInteraction& interaction) override; void SetBoundsDirtyImpl() override; void InvalidateImpl() override; - /// Unchanging data set once for the angular manipulator. + //! Unchanging data set once for the angular manipulator. struct Fixed { - AZ::Vector3 m_axis = AZ::Vector3::CreateAxisX(); ///< Axis for this angular manipulator to rotate around. + AZ::Vector3 m_axis = AZ::Vector3::CreateAxisX(); //!< Axis for this angular manipulator to rotate around. }; - /// Initial data recorded when a press first happens with an angular manipulator. + //! Initial data recorded when a press first happens with an angular manipulator. struct StartInternal { - AZ::Transform m_worldFromLocal; ///< Initial transform when pressed. - AZ::Transform m_localTransform; ///< Additional transform (offset) to apply to manipulator. - AZ::Vector3 m_planePoint; ///< Position on plane to use for ray intersection. - AZ::Vector3 m_planeNormal; ///< Normal of plane to use for ray intersection. + AZ::Transform m_worldFromLocal; //!< Initial transform when pressed. + AZ::Transform m_localTransform; //!< Additional transform (offset) to apply to manipulator. + AZ::Vector3 m_planePoint; //!< Position on plane to use for ray intersection. + AZ::Vector3 m_planeNormal; //!< Normal of plane to use for ray intersection. }; - /// Current data recorded each frame during an interaction with an angular manipulator. + //! Current data recorded each frame during an interaction with an angular manipulator. struct CurrentInternal { - float m_preSnapRadians = 0.0f; ///< Amount of rotation before a snap (snap increment accumulator). - float m_radians = 0.0f; ///< Amount of rotation about the axis for this action. - AZ::Vector3 m_worldHitPosition; ///< Initial world space hit position. + float m_preSnapRadians = 0.0f; //!< Amount of rotation before a snap (snap increment accumulator). + float m_radians = 0.0f; //!< Amount of rotation about the axis for this action. + AZ::Vector3 m_worldHitPosition; //!< Initial world space hit position. }; - /// Wrap start and current internal data during an interaction with an angular manipulator. + //! Wrap start and current internal data during an interaction with an angular manipulator. struct ActionInternal { StartInternal m_start; @@ -135,16 +141,25 @@ namespace AzToolsFramework MouseActionCallback m_onLeftMouseUpCallback = nullptr; MouseActionCallback m_onMouseMoveCallback = nullptr; - AZStd::unique_ptr m_manipulatorView; ///< Look of manipulator. + AZStd::unique_ptr m_manipulatorView; //!< Look of manipulator. static ActionInternal CalculateManipulationDataStart( - const Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Transform& localTransform, - const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, float rayDistance); + const Fixed& fixed, + const AZ::Transform& worldFromLocal, + const AZ::Transform& localTransform, + const AZ::Vector3& rayOrigin, + const AZ::Vector3& rayDirection, + float rayDistance); static Action CalculateManipulationDataAction( - const Fixed& fixed, ActionInternal& actionInternal, const AZ::Transform& worldFromLocal, - const AZ::Transform& localTransform, bool snapping, float angleStepDegrees, - const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, + const Fixed& fixed, + ActionInternal& actionInternal, + const AZ::Transform& worldFromLocal, + const AZ::Transform& localTransform, + bool snapping, + float angleStepDegrees, + const AZ::Vector3& rayOrigin, + const AZ::Vector3& rayDirection, ViewportInteraction::KeyboardModifiers keyboardModifiers); }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BaseManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BaseManipulator.cpp index 955d10d3bd..73d0dc72be 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BaseManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BaseManipulator.cpp @@ -1,33 +1,30 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "BaseManipulator.h" #include -#include #include +#include namespace AzToolsFramework { - AZ_CVAR( - bool, cl_manipulatorDrawDebug, false, nullptr, AZ::ConsoleFunctorFlags::Null, - "Enable debug drawing for Manipulators"); + AZ_CVAR(bool, cl_manipulatorDrawDebug, false, nullptr, AZ::ConsoleFunctorFlags::Null, "Enable debug drawing for Manipulators"); const AZ::Color BaseManipulator::s_defaultMouseOverColor = AZ::Color(1.0f, 1.0f, 0.0f, 1.0f); // yellow AZ_CLASS_ALLOCATOR_IMPL(BaseManipulator, AZ::SystemAllocator, 0) - static bool EntityIdAndEntityComponentIdComparison( - const AZ::EntityId entityId, const AZ::EntityComponentIdPair& entityComponentId) + static bool EntityIdAndEntityComponentIdComparison(const AZ::EntityId entityId, const AZ::EntityComponentIdPair& entityComponentId) { return entityId == entityComponentId.GetEntityId(); } @@ -38,8 +35,7 @@ namespace AzToolsFramework EndUndoBatch(); } - bool BaseManipulator::OnLeftMouseDown( - const ViewportInteraction::MouseInteraction& interaction, const float rayIntersectionDistance) + bool BaseManipulator::OnLeftMouseDown(const ViewportInteraction::MouseInteraction& interaction, const float rayIntersectionDistance) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -57,8 +53,7 @@ namespace AzToolsFramework (*this.*m_onLeftMouseDownImpl)(interaction, rayIntersectionDistance); - ToolsApplicationNotificationBus::Broadcast( - &ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values); + ToolsApplicationNotificationBus::Broadcast(&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values); return true; } @@ -66,8 +61,7 @@ namespace AzToolsFramework return false; } - bool BaseManipulator::OnRightMouseDown( - const ViewportInteraction::MouseInteraction& interaction, const float rayIntersectionDistance) + bool BaseManipulator::OnRightMouseDown(const ViewportInteraction::MouseInteraction& interaction, const float rayIntersectionDistance) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -85,8 +79,7 @@ namespace AzToolsFramework (*this.*m_onRightMouseDownImpl)(interaction, rayIntersectionDistance); - ToolsApplicationNotificationBus::Broadcast( - &ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values); + ToolsApplicationNotificationBus::Broadcast(&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values); return true; } @@ -118,8 +111,7 @@ namespace AzToolsFramework EndUndoBatch(); } - bool BaseManipulator::OnMouseOver( - const ManipulatorId manipulatorId, const ViewportInteraction::MouseInteraction& interaction) + bool BaseManipulator::OnMouseOver(const ManipulatorId manipulatorId, const ViewportInteraction::MouseInteraction& interaction) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -132,8 +124,7 @@ namespace AzToolsFramework { OnMouseWheelImpl(interaction); - ToolsApplicationNotificationBus::Broadcast( - &ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values); + ToolsApplicationNotificationBus::Broadcast(&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values); } void BaseManipulator::OnMouseMove(const ViewportInteraction::MouseInteraction& interaction) @@ -142,16 +133,13 @@ namespace AzToolsFramework if (!m_performingAction) { - AZ_Warning( - "Manipulators", false, - "MouseMove action received, but this manipulator is not performing an action"); + AZ_Warning("Manipulators", false, "MouseMove action received, but this manipulator is not performing an action"); return; } // ensure property grid (entity inspector) values are refreshed - ToolsApplicationNotificationBus::Broadcast( - &ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values); + ToolsApplicationNotificationBus::Broadcast(&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values); OnMouseMoveImpl(interaction); } @@ -170,16 +158,14 @@ namespace AzToolsFramework Unregister(); } - ManipulatorManagerRequestBus::Event(managerId, - &ManipulatorManagerRequestBus::Events::RegisterManipulator, shared_from_this()); + ManipulatorManagerRequestBus::Event(managerId, &ManipulatorManagerRequestBus::Events::RegisterManipulator, shared_from_this()); } void BaseManipulator::Unregister() { // if the manipulator has already been unregistered, the m_manipulatorManagerId // should be invalid which makes the call below a no-op. - ManipulatorManagerRequestBus::Event(m_manipulatorManagerId, - &ManipulatorManagerRequestBus::Events::UnregisterManipulator, this); + ManipulatorManagerRequestBus::Event(m_manipulatorManagerId, &ManipulatorManagerRequestBus::Events::UnregisterManipulator, this); } void BaseManipulator::Invalidate() @@ -197,8 +183,7 @@ namespace AzToolsFramework if (m_performingAction) { AZ_Warning( - "Manipulators", false, - "MouseDown action received, but the manipulator (id: %d) is still performing an action", + "Manipulators", false, "MouseDown action received, but the manipulator (id: %d) is still performing an action", GetManipulatorId()); return; @@ -214,8 +199,7 @@ namespace AzToolsFramework if (!m_performingAction) { AZ_Warning( - "Manipulators", false, - "MouseUp action received, but this manipulator (id: %d) didn't receive MouseDown action before", + "Manipulators", false, "MouseUp action received, but this manipulator (id: %d) didn't receive MouseDown action before", GetManipulatorId()); return; } @@ -263,13 +247,13 @@ namespace AzToolsFramework if (entityComponentIdPair.GetComponentId() != AZ::InvalidComponentId) { PropertyEditorEntityChangeNotificationBus::Event( - entityComponentIdPair.GetEntityId(), - &PropertyEditorEntityChangeNotifications::OnEntityComponentPropertyChanged, + entityComponentIdPair.GetEntityId(), &PropertyEditorEntityChangeNotifications::OnEntityComponentPropertyChanged, entityComponentIdPair.GetComponentId()); } else { - AZ_Warning("Manipulators", false, + AZ_Warning( + "Manipulators", false, "This Manipulator was only registered with an EntityId and not an EntityComponentIdPair. " "Please use AddEntityComponentIdPair() instead of AddEntityId() when registering what this " "Manipulator is changing."); @@ -280,8 +264,7 @@ namespace AzToolsFramework for (const AZ::Component* component : entity->GetComponents()) { PropertyEditorEntityChangeNotificationBus::Event( - entity->GetId(), &PropertyEditorEntityChangeNotifications::OnEntityComponentPropertyChanged, - component->GetId()); + entity->GetId(), &PropertyEditorEntityChangeNotifications::OnEntityComponentPropertyChanged, component->GetId()); } } } @@ -298,9 +281,7 @@ namespace AzToolsFramework { // look for a match (keep looking in case we have several entity ids with different component ids) const auto entityComponentPairId = - m_entityComponentIdPairs.find_as( - entityId, AZStd::hash(), - &EntityIdAndEntityComponentIdComparison); + m_entityComponentIdPairs.find_as(entityId, AZStd::hash(), &EntityIdAndEntityComponentIdComparison); // update the afterErased variable so we can return an iterator // to the correct position in the container. @@ -334,9 +315,8 @@ namespace AzToolsFramework bool BaseManipulator::HasEntityId(const AZ::EntityId entityId) const { - return m_entityComponentIdPairs.find_as( - entityId, AZStd::hash(), - &EntityIdAndEntityComponentIdComparison) != m_entityComponentIdPairs.end(); + return m_entityComponentIdPairs.find_as(entityId, AZStd::hash(), &EntityIdAndEntityComponentIdComparison) != + m_entityComponentIdPairs.end(); } bool BaseManipulator::HasEntityComponentIdPair(const AZ::EntityComponentIdPair& entityComponentIdPair) const @@ -346,7 +326,8 @@ namespace AzToolsFramework void Manipulators::Register(const ManipulatorManagerId manipulatorManagerId) { - ProcessManipulators([manipulatorManagerId](BaseManipulator* manipulator) + ProcessManipulators( + [manipulatorManagerId](BaseManipulator* manipulator) { manipulator->Register(manipulatorManagerId); }); @@ -354,7 +335,8 @@ namespace AzToolsFramework void Manipulators::Unregister() { - ProcessManipulators([](BaseManipulator* manipulator) + ProcessManipulators( + [](BaseManipulator* manipulator) { if (manipulator->Registered()) { @@ -365,7 +347,8 @@ namespace AzToolsFramework void Manipulators::SetBoundsDirty() { - ProcessManipulators([](BaseManipulator* manipulator) + ProcessManipulators( + [](BaseManipulator* manipulator) { manipulator->SetBoundsDirty(); }); @@ -373,7 +356,8 @@ namespace AzToolsFramework void Manipulators::AddEntityComponentIdPair(const AZ::EntityComponentIdPair& entityComponentIdPair) { - ProcessManipulators([&entityComponentIdPair](BaseManipulator* manipulator) + ProcessManipulators( + [&entityComponentIdPair](BaseManipulator* manipulator) { manipulator->AddEntityComponentIdPair(entityComponentIdPair); }); @@ -381,7 +365,8 @@ namespace AzToolsFramework void Manipulators::RemoveEntityComponentIdPair(const AZ::EntityComponentIdPair& entityComponentIdPair) { - ProcessManipulators([&entityComponentIdPair](BaseManipulator* manipulator) + ProcessManipulators( + [&entityComponentIdPair](BaseManipulator* manipulator) { manipulator->RemoveEntityComponentIdPair(entityComponentIdPair); }); @@ -389,7 +374,8 @@ namespace AzToolsFramework void Manipulators::RemoveEntityId(const AZ::EntityId entityId) { - ProcessManipulators([entityId](BaseManipulator* manipulator) + ProcessManipulators( + [entityId](BaseManipulator* manipulator) { manipulator->RemoveEntityId(entityId); }); @@ -398,7 +384,8 @@ namespace AzToolsFramework bool Manipulators::PerformingAction() { bool performingAction = false; - ProcessManipulators([&performingAction](BaseManipulator* manipulator) + ProcessManipulators( + [&performingAction](BaseManipulator* manipulator) { if (manipulator->PerformingAction()) { @@ -412,7 +399,8 @@ namespace AzToolsFramework bool Manipulators::Registered() { bool registered = false; - ProcessManipulators([®istered](BaseManipulator* manipulator) + ProcessManipulators( + [®istered](BaseManipulator* manipulator) { if (manipulator->Registered()) { @@ -470,8 +458,12 @@ namespace AzToolsFramework namespace Internal { - bool CalculateRayPlaneIntersectingPoint(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, - const AZ::Vector3& pointOnPlane, const AZ::Vector3& planeNormal, AZ::Vector3& resultIntersectingPoint) + bool CalculateRayPlaneIntersectingPoint( + const AZ::Vector3& rayOrigin, + const AZ::Vector3& rayDirection, + const AZ::Vector3& pointOnPlane, + const AZ::Vector3& planeNormal, + AZ::Vector3& resultIntersectingPoint) { float t = 0.0f; if (AZ::Intersect::IntersectRayPlane(rayOrigin, rayDirection, pointOnPlane, planeNormal, t) > 0) @@ -484,11 +476,12 @@ namespace AzToolsFramework } AZ::Vector3 TryConstrainHitPositionToView( - const AZ::Vector3& currentLocalHitPosition, const AZ::Vector3& startLocalHitPosition, - const AZ::Transform& localFromWorld, const AzFramework::CameraState& cameraState) + const AZ::Vector3& currentLocalHitPosition, + const AZ::Vector3& startLocalHitPosition, + const AZ::Transform& localFromWorld, + const AzFramework::CameraState& cameraState) { - if (currentLocalHitPosition.GetDistance(localFromWorld.TransformPoint(cameraState.m_position)) - > cameraState.m_farClip) + if (currentLocalHitPosition.GetDistance(localFromWorld.TransformPoint(cameraState.m_position)) > cameraState.m_farClip) { return startLocalHitPosition; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BaseManipulator.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BaseManipulator.h index 2b078f62b7..04f2bc456b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BaseManipulator.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BaseManipulator.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -22,13 +22,13 @@ #include #include #include -#include "ManipulatorSpace.h" +#include namespace AzFramework { struct CameraState; class DebugDisplayRequests; -} +} // namespace AzFramework namespace AzToolsFramework { @@ -46,9 +46,8 @@ namespace AzToolsFramework struct ManipulatorManagerState; - /// The base class for manipulators, providing interfaces for users of manipulators to talk to. - class BaseManipulator - : public AZStd::enable_shared_from_this + //! The base class for manipulators, providing interfaces for users of manipulators to talk to. + class BaseManipulator : public AZStd::enable_shared_from_this { public: AZ_CLASS_ALLOCATOR_DECL @@ -61,139 +60,181 @@ namespace AzToolsFramework using EntityComponentIds = AZStd::unordered_set; - /// Callback for the event when the mouse pointer is over this manipulator and the left mouse button is pressed. - /// @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera through the mouse pointer. - /// @param rayIntersectionDistance The parameter value in the ray's explicit equation that represents the intersecting point on the target manipulator in world space. - /// @return Return true if OnLeftMouseDownImpl was attached and will be used. + //! Callback for the event when the mouse pointer is over this manipulator and the left mouse button is pressed. + //! @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera + //! through the mouse pointer. + //! @param rayIntersectionDistance The parameter value in the ray's explicit equation that represents the intersecting point on the + //! target manipulator in world space. + //! @return Return true if OnLeftMouseDownImpl was attached and will be used. bool OnLeftMouseDown(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance); - /// Callback for the event when this manipulator is active and the left mouse button is released. - /// @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera through the mouse pointer. + //! Callback for the event when this manipulator is active and the left mouse button is released. + //! @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera + //! through the mouse pointer. void OnLeftMouseUp(const ViewportInteraction::MouseInteraction& interaction); - /// Callback for the event when the mouse pointer is over this manipulator and the right mouse button is pressed . - /// @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera through the mouse pointer. - /// @param rayIntersectionDistance The parameter value in the ray's explicit equation that represents the intersecting point on the target manipulator in world space. - /// @return Return true if OnRightMouseDownImpl was attached and will be used. + //! Callback for the event when the mouse pointer is over this manipulator and the right mouse button is pressed . + //! @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera + //! through the mouse pointer. + //! @param rayIntersectionDistance The parameter value in the ray's explicit equation that represents the intersecting point on the + //! target manipulator in world space. + //! @return Return true if OnRightMouseDownImpl was attached and will be used. bool OnRightMouseDown(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance); - /// Callback for the event when this manipulator is active and the right mouse button is released. - /// @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera through the mouse pointer. + //! Callback for the event when this manipulator is active and the right mouse button is released. + //! @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera + //! through the mouse pointer. void OnRightMouseUp(const ViewportInteraction::MouseInteraction& interaction); - /// Callback for the event when this manipulator is active and the mouse is moved. - /// @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera through the mouse pointer. + //! Callback for the event when this manipulator is active and the mouse is moved. + //! @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera + //! through the mouse pointer. void OnMouseMove(const ViewportInteraction::MouseInteraction& interaction); - /// Callback for the event when this manipulator is active and the mouse wheel is scrolled. - /// @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera through the mouse pointer. + //! Callback for the event when this manipulator is active and the mouse wheel is scrolled. + //! @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera + //! through the mouse pointer. void OnMouseWheel(const ViewportInteraction::MouseInteraction& interaction); - /// This function changes the state indicating whether the manipulator is under the mouse pointer. - /// It is called in the event of OnMouseMove and OnMouseWheel only when there is no manipulator currently performing actions. + //! This function changes the state indicating whether the manipulator is under the mouse pointer. + //! It is called in the event of OnMouseMove and OnMouseWheel only when there is no manipulator currently performing actions. bool OnMouseOver(ManipulatorId manipulatorId, const ViewportInteraction::MouseInteraction& interaction); - /// Register itself to a manipulator manager so that it can receive various mouse events and perform manipulations. - /// @param managerId The id identifying a unique manipulator manager. + //! Register itself to a manipulator manager so that it can receive various mouse events and perform manipulations. + //! @param managerId The id identifying a unique manipulator manager. void Register(ManipulatorManagerId managerId); - /// Unregister itself from the manipulator manager it was registered with. + //! Unregister itself from the manipulator manager it was registered with. void Unregister(); - /// Bounds will need to be recalculated next time we render. + //! Bounds will need to be recalculated next time we render. void SetBoundsDirty(); - /// Is this manipulator currently registered with a manipulator manager. + //! Is this manipulator currently registered with a manipulator manager. bool Registered() const { - return m_manipulatorId != InvalidManipulatorId && - m_manipulatorManagerId != InvalidManipulatorManagerId; + return m_manipulatorId != InvalidManipulatorId && m_manipulatorManagerId != InvalidManipulatorManagerId; } - /// Is the manipulator in the middle of an action (between mouse down and mouse up). - bool PerformingAction() const { return m_performingAction; } + //! Is the manipulator in the middle of an action (between mouse down and mouse up). + bool PerformingAction() const + { + return m_performingAction; + } - /// Is the mouse currently over the manipulator (intersecting manipulator bound). - bool MouseOver() const { return m_mouseOver; } + //! Is the mouse currently over the manipulator (intersecting manipulator bound). + bool MouseOver() const + { + return m_mouseOver; + } - /// The unique id of this manipulator. - ManipulatorId GetManipulatorId() const { return m_manipulatorId; } + //! The unique id of this manipulator. + ManipulatorId GetManipulatorId() const + { + return m_manipulatorId; + } - /// The unique id of the manager this manipulator was registered with. - ManipulatorManagerId GetManipulatorManagerId() const { return m_manipulatorManagerId; } + //! The unique id of the manager this manipulator was registered with. + ManipulatorManagerId GetManipulatorManagerId() const + { + return m_manipulatorManagerId; + } - /// Returns all EntityComponentIdPairs associated with this manipulator. + //! Returns all EntityComponentIdPairs associated with this manipulator. const EntityComponentIds& EntityComponentIdPairs() const { return m_entityComponentIdPairs; } - /// Add an entity and component the manipulator is responsible for. + //! Add an entity and component the manipulator is responsible for. void AddEntityComponentIdPair(const AZ::EntityComponentIdPair& entityComponentIdPair); - /// Remove an entity from being affected by this manipulator. - /// @note All components on this entity registered with the manipulator will be removed. + //! Remove an entity from being affected by this manipulator. + //! @note All components on this entity registered with the manipulator will be removed. EntityComponentIds::iterator RemoveEntityId(AZ::EntityId entityId); - /// Remove a specific component (via a EntityComponentIdPair) being affected by this manipulator. + //! Remove a specific component (via a EntityComponentIdPair) being affected by this manipulator. EntityComponentIds::iterator RemoveEntityComponentIdPair(const AZ::EntityComponentIdPair& entityComponentIdPair); - /// Is this entity currently being tracked by this manipulator. + //! Is this entity currently being tracked by this manipulator. bool HasEntityId(AZ::EntityId entityId) const; - /// Is this entity component pair currently being tracked by this manipulator. + //! Is this entity component pair currently being tracked by this manipulator. bool HasEntityComponentIdPair(const AZ::EntityComponentIdPair& entityComponentIdPair) const; - /// Forward a mouse over event in a case where we need the manipulator to immediately refresh. - /// @note Only call this when a mouse over event has just happened. + //! Forward a mouse over event in a case where we need the manipulator to immediately refresh. + //! @note Only call this when a mouse over event has just happened. void ForwardMouseOverEvent(const ViewportInteraction::MouseInteraction& interaction); static const AZ::Color s_defaultMouseOverColor; protected: - /// Protected constructor. + //! Protected constructor. BaseManipulator() = default; - /// Called when unregistering - users of manipulators should not call it directly. + //! Called when unregistering - users of manipulators should not call it directly. void Invalidate(); - /// The implementation to override in a derived class for Invalidate. - virtual void InvalidateImpl() {} + //! The implementation to override in a derived class for Invalidate. + virtual void InvalidateImpl() + { + } - /// The implementation to override in a derived class for OnLeftMouseDown. - /// Note: When implementing this function you must also call AttachLeftMouseDownImpl to ensure - /// m_onLeftMouseDownImpl is set to OnLeftMouseDownImpl, otherwise it will not be called - virtual void OnLeftMouseDownImpl( - const ViewportInteraction::MouseInteraction& /*interaction*/, float /*rayIntersectionDistance*/) {} - void AttachLeftMouseDownImpl() { m_onLeftMouseDownImpl = &BaseManipulator::OnLeftMouseDownImpl; } + //! The implementation to override in a derived class for OnLeftMouseDown. + //! Note: When implementing this function you must also call AttachLeftMouseDownImpl to ensure + //! m_onLeftMouseDownImpl is set to OnLeftMouseDownImpl, otherwise it will not be called + virtual void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& /*interaction*/, float /*rayIntersectionDistance*/) + { + } - /// The implementation to override in a derived class for OnRightMouseDown. - /// Note: When implementing this function you must also call AttachRightMouseDownImpl to ensure - /// m_onRightMouseDownImpl is set to OnRightMouseDownImpl, otherwise it will not be called - virtual void OnRightMouseDownImpl( - const ViewportInteraction::MouseInteraction& /*interaction*/, float /*rayIntersectionDistance*/) {} - void AttachRightMouseDownImpl() { m_onRightMouseDownImpl = &BaseManipulator::OnRightMouseDownImpl; } + void AttachLeftMouseDownImpl() + { + m_onLeftMouseDownImpl = &BaseManipulator::OnLeftMouseDownImpl; + } - /// The implementation to override in a derived class for OnLeftMouseUp. - virtual void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& /*interaction*/) {} + //! The implementation to override in a derived class for OnRightMouseDown. + //! Note: When implementing this function you must also call AttachRightMouseDownImpl to ensure + //! m_onRightMouseDownImpl is set to OnRightMouseDownImpl, otherwise it will not be called + virtual void OnRightMouseDownImpl(const ViewportInteraction::MouseInteraction& /*interaction*/, float /*rayIntersectionDistance*/) + { + } - /// The implementation to override in a derived class for OnRightMouseUp. - virtual void OnRightMouseUpImpl(const ViewportInteraction::MouseInteraction& /*interaction*/) {} + void AttachRightMouseDownImpl() + { + m_onRightMouseDownImpl = &BaseManipulator::OnRightMouseDownImpl; + } - /// The implementation to override in a derived class for OnMouseMove. - virtual void OnMouseMoveImpl(const ViewportInteraction::MouseInteraction& /*interaction*/) {} + //! The implementation to override in a derived class for OnLeftMouseUp. + virtual void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& /*interaction*/) + { + } - /// The implementation to override in a derived class for OnMouseOver. - virtual void OnMouseOverImpl( - ManipulatorId /*manipulatorId*/, const ViewportInteraction::MouseInteraction& /*interaction*/) {} + //! The implementation to override in a derived class for OnRightMouseUp. + virtual void OnRightMouseUpImpl(const ViewportInteraction::MouseInteraction& /*interaction*/) + { + } - /// The implementation to override in a derived class for OnMouseWheel. - virtual void OnMouseWheelImpl(const ViewportInteraction::MouseInteraction& /*interaction*/) {} + //! The implementation to override in a derived class for OnMouseMove. + virtual void OnMouseMoveImpl(const ViewportInteraction::MouseInteraction& /*interaction*/) + { + } - /// The implementation to override in a derived class for SetBoundsDirty. - virtual void SetBoundsDirtyImpl() {} + //! The implementation to override in a derived class for OnMouseOver. + virtual void OnMouseOverImpl(ManipulatorId /*manipulatorId*/, const ViewportInteraction::MouseInteraction& /*interaction*/) + { + } + + //! The implementation to override in a derived class for OnMouseWheel. + virtual void OnMouseWheelImpl(const ViewportInteraction::MouseInteraction& /*interaction*/) + { + } + + //! The implementation to override in a derived class for SetBoundsDirty. + virtual void SetBoundsDirtyImpl() + { + } - /// Rendering for the manipulator - it is recommended drawing be delegated to a ManipulatorView. + //! Rendering for the manipulator - it is recommended drawing be delegated to a ManipulatorView. virtual void Draw( const ManipulatorManagerState& managerState, AzFramework::DebugDisplayRequests& debugDisplay, @@ -202,39 +243,39 @@ namespace AzToolsFramework private: friend class ManipulatorManager; - AZStd::unordered_set m_entityComponentIdPairs; ///< The entities this manipulator is associated with. + AZStd::unordered_set m_entityComponentIdPairs; //!< The entities this manipulator is associated with. - ManipulatorId m_manipulatorId = InvalidManipulatorId; ///< The unique id of this manipulator. - ManipulatorManagerId m_manipulatorManagerId = InvalidManipulatorManagerId; ///< The manager this manipulator was registered with. - UndoSystem::URSequencePoint* m_undoBatch = nullptr; ///< Undo active while mouse is pressed. - bool m_performingAction = false; ///< After mouse down and before mouse up. - bool m_mouseOver = false; ///< Is the mouse pointer over the manipulator bound. + ManipulatorId m_manipulatorId = InvalidManipulatorId; //!< The unique id of this manipulator. + ManipulatorManagerId m_manipulatorManagerId = InvalidManipulatorManagerId; //!< The manager this manipulator was registered with. + UndoSystem::URSequencePoint* m_undoBatch = nullptr; //!< Undo active while mouse is pressed. + bool m_performingAction = false; //!< After mouse down and before mouse up. + bool m_mouseOver = false; //!< Is the mouse pointer over the manipulator bound. - /// Member function pointers to OnLeftMouseDownImpl and OnRightMouseDownImpl. - /// Set in AttachLeft/RightMouseDownImpl. + //! Member function pointers to OnLeftMouseDownImpl and OnRightMouseDownImpl. + //! Set in AttachLeft/RightMouseDownImpl. void (BaseManipulator::*m_onLeftMouseDownImpl)( const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) = nullptr; void (BaseManipulator::*m_onRightMouseDownImpl)( const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) = nullptr; - /// Update the mouseOver state for this manipulator. + //! Update the mouseOver state for this manipulator. void UpdateMouseOver(ManipulatorId manipulatorId); - /// Manage correctly ending the undo batch. + //! Manage correctly ending the undo batch. void EndUndoBatch(); - /// Record an action as having started. + //! Record an action as having started. void BeginAction(); - /// Record an action as having stopped. + //! Record an action as having stopped. void EndAction(); - /// Let other systems (UI) know that a component property has been modified by a manipulator. + //! Let other systems (UI) know that a component property has been modified by a manipulator. void NotifyEntityComponentPropertyChanged(); }; - /// Base class to be used when composing aggregate manipulator types - wraps some - /// common functionality all manipulators need. + //! Base class to be used when composing aggregate manipulator types - wraps some + //! common functionality all manipulators need. class Manipulators { public: @@ -249,8 +290,10 @@ namespace AzToolsFramework bool PerformingAction(); bool Registered(); - /// Refresh the Manipulator and/or View based on the current view position. - virtual void RefreshView(const AZ::Vector3& /*worldViewPosition*/) {} + //! Refresh the Manipulator and/or View based on the current view position. + virtual void RefreshView(const AZ::Vector3& /*worldViewPosition*/) + { + } const AZ::Transform& GetLocalTransform() const; const AZ::Transform& GetSpace() const; @@ -262,39 +305,59 @@ namespace AzToolsFramework void SetNonUniformScale(const AZ::Vector3& nonUniformScale); protected: - /// Common processing for base manipulator type - Implement for all - /// individual manipulators used in an aggregate manipulator. + //! Common processing for base manipulator type - Implement for all + //! individual manipulators used in an aggregate manipulator. virtual void ProcessManipulators(const AZStd::function&) = 0; - ///@{ - /// Allows implementers to perform additional logic when updating the location of the manipulator group. - virtual void SetSpaceImpl([[maybe_unused]] const AZ::Transform& worldFromLocal) {} - virtual void SetLocalTransformImpl([[maybe_unused]] const AZ::Transform& localTransform) {} - virtual void SetLocalPositionImpl([[maybe_unused]] const AZ::Vector3& localPosition) {} - virtual void SetLocalOrientationImpl([[maybe_unused]] const AZ::Quaternion& localOrientation) {} - virtual void SetNonUniformScaleImpl([[maybe_unused]] const AZ::Vector3& nonUniformScale) {} - ///@} + //!@{ + //! Allows implementers to perform additional logic when updating the location of the manipulator group. + virtual void SetSpaceImpl([[maybe_unused]] const AZ::Transform& worldFromLocal) + { + } + + virtual void SetLocalTransformImpl([[maybe_unused]] const AZ::Transform& localTransform) + { + } + + virtual void SetLocalPositionImpl([[maybe_unused]] const AZ::Vector3& localPosition) + { + } + + virtual void SetLocalOrientationImpl([[maybe_unused]] const AZ::Quaternion& localOrientation) + { + } + + virtual void SetNonUniformScaleImpl([[maybe_unused]] const AZ::Vector3& nonUniformScale) + { + } + //!@} - ManipulatorSpaceWithLocalTransform m_manipulatorSpaceWithLocalTransform; ///< The space and local transform for the manipulators. + ManipulatorSpaceWithLocalTransform m_manipulatorSpaceWithLocalTransform; //!< The space and local transform for the manipulators. }; namespace Internal { - /// This helper function calculates the intersecting point between a ray and a plane. - /// @param rayOrigin The origin of the ray to test. - /// @param rayDirection The direction of the ray to test. - /// @param maxRayLength - /// @param pointOnPlane A point on the plane. - /// @param planeNormal The normal vector of the plane. - /// @param[out] resultIntersectingPoint This stores the result intersecting point. It will be left unchanged - /// if there is no intersection between the ray and the plane. - /// @return Was there an intersection - bool CalculateRayPlaneIntersectingPoint(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, - const AZ::Vector3& pointOnPlane, const AZ::Vector3& planeNormal, AZ::Vector3& resultIntersectingPoint); - - /// Returns startLocalHitPosition if currentLocalHitPosition is further away than the camera's far clip plane. + //! This helper function calculates the intersecting point between a ray and a plane. + //! @param rayOrigin The origin of the ray to test. + //! @param rayDirection The direction of the ray to test. + //! @param maxRayLength The maximum length of the ray to test. + //! @param pointOnPlane A point on the plane. + //! @param planeNormal The normal vector of the plane. + //! @param[out] resultIntersectingPoint This stores the result intersecting point. It will be left unchanged + //! if there is no intersection between the ray and the plane. + //! @return Was there an intersection + bool CalculateRayPlaneIntersectingPoint( + const AZ::Vector3& rayOrigin, + const AZ::Vector3& rayDirection, + const AZ::Vector3& pointOnPlane, + const AZ::Vector3& planeNormal, + AZ::Vector3& resultIntersectingPoint); + + //! Returns startLocalHitPosition if currentLocalHitPosition is further away than the camera's far clip plane. AZ::Vector3 TryConstrainHitPositionToView( - const AZ::Vector3& currentLocalHitPosition, const AZ::Vector3& startLocalHitPosition, - const AZ::Transform& localFromWorld, const AzFramework::CameraState& cameraState); - } + const AZ::Vector3& currentLocalHitPosition, + const AZ::Vector3& startLocalHitPosition, + const AZ::Transform& localFromWorld, + const AzFramework::CameraState& cameraState); + } // namespace Internal } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BoxManipulatorRequestBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BoxManipulatorRequestBus.h index 05da73fa20..69920f5f52 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BoxManipulatorRequestBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BoxManipulatorRequestBus.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -21,31 +21,30 @@ namespace AZ namespace AzToolsFramework { - /// Interface for handling box manipulator requests. - /// Used by \ref BoxComponentMode. - class BoxManipulatorRequests - : public AZ::EntityComponentBus + //! Interface for handling box manipulator requests. + //! Used by \ref BoxComponentMode. + class BoxManipulatorRequests : public AZ::EntityComponentBus { public: - /// Get the X/Y/Z dimensions of the box shape/collider. + //! Get the X/Y/Z dimensions of the box shape/collider. virtual AZ::Vector3 GetDimensions() = 0; - /// Set the X/Y/Z dimensions of the box shape/collider. + //! Set the X/Y/Z dimensions of the box shape/collider. virtual void SetDimensions(const AZ::Vector3& dimensions) = 0; - /// Get the transform of the box shape/collider. - /// This is used by \ref BoxComponentMode instead of the \ref \AZ::TransformBus - /// because a collider may have an additional translation/orientation offset from - /// the Entity transform. + //! Get the transform of the box shape/collider. + //! This is used by \ref BoxComponentMode instead of the \ref \AZ::TransformBus + //! because a collider may have an additional translation/orientation offset from + //! the Entity transform. virtual AZ::Transform GetCurrentTransform() = 0; - /// Get the scale currently applied to the box. - /// With the Box Shape, the largest x/y/z component is taken - /// so scale is always uniform, with colliders the scale may - /// be different per component. + //! Get the scale currently applied to the box. + //! With the Box Shape, the largest x/y/z component is taken + //! so scale is always uniform, with colliders the scale may + //! be different per component. virtual AZ::Vector3 GetBoxScale() = 0; protected: ~BoxManipulatorRequests() = default; }; - /// Type to inherit to implement BoxManipulatorRequests + //! Type to inherit to implement BoxManipulatorRequests using BoxManipulatorRequestBus = AZ::EBus; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.cpp index 55a8464ba6..c8be488c91 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "EditorVertexSelection.h" @@ -16,10 +16,10 @@ #include #include #include -#include #include -#include #include +#include +#include #include #include #include @@ -37,7 +37,7 @@ using Vertex3LookupReverseIter = namespace std { - template <> + template<> struct iterator_traits { using difference_type = typename Vertex2LookupReverseIter::difference_type; @@ -47,7 +47,7 @@ namespace std using reference = typename Vertex2LookupReverseIter::reference; }; - template <> + template<> struct iterator_traits { using difference_type = typename Vertex3LookupReverseIter::difference_type; @@ -56,7 +56,7 @@ namespace std using pointer = typename Vertex3LookupReverseIter::pointer; using reference = typename Vertex3LookupReverseIter::reference; }; -} +} // namespace std namespace AzToolsFramework { @@ -73,14 +73,11 @@ namespace AzToolsFramework OnEntityComponentPropertyChanged(entityComponentIdPair); // ensure property grid values are refreshed - ToolsApplicationNotificationBus::Broadcast( - &ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, - Refresh_EntireTree); + ToolsApplicationNotificationBus::Broadcast(&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_EntireTree); } template - bool EditorVertexSelectionBase::HandleMouse( - const ViewportInteraction::MouseInteractionEvent& mouseInteraction) + bool EditorVertexSelectionBase::HandleMouse(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) { m_editorBoxSelect.HandleMouseInteraction(mouseInteraction); @@ -115,18 +112,17 @@ namespace AzToolsFramework } template - void EditorVertexSelectionBase::SnapVerticesToTerrain( - const ViewportInteraction::MouseInteractionEvent& mouseInteraction) + void EditorVertexSelectionBase::SnapVerticesToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) { ScopedUndoBatch surfaceSnapUndo("Snap to Surface"); ScopedUndoBatch::MarkEntityDirty(GetEntityId()); const int viewportId = mouseInteraction.m_mouseInteraction.m_interactionId.m_viewportId; // get unsnapped terrain position (world space) - AZ::Vector3 worldSurfacePosition = AZ::Vector3::CreateZero();; + AZ::Vector3 worldSurfacePosition = AZ::Vector3::CreateZero(); + ; ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult( - worldSurfacePosition, viewportId, - &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain, + worldSurfacePosition, viewportId, &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain, mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates); AZ::Transform worldFromLocal; @@ -136,8 +132,7 @@ namespace AzToolsFramework // convert to local space - snap if enabled const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId); const AZ::Vector3 localFinalSurfacePosition = gridSnapParams.m_gridSnap - ? CalculateSnappedTerrainPosition( - worldSurfacePosition, worldFromLocal, viewportId, gridSnapParams.m_gridSize) + ? CalculateSnappedTerrainPosition(worldSurfacePosition, worldFromLocal, viewportId, gridSnapParams.m_gridSize) : localFromWorld.TransformPoint(worldSurfacePosition); SetSelectedPosition(localFinalSurfacePosition); @@ -145,17 +140,16 @@ namespace AzToolsFramework OnEntityComponentPropertyChanged(GetEntityComponentIdPair()); // ensure property grid values are refreshed - ToolsApplicationNotificationBus::Broadcast( - &ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, - Refresh_Values); + ToolsApplicationNotificationBus::Broadcast(&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values); } - /// Iterate over all vertices currently associated with the translation manipulator and update their - /// positions by taking their starting positions and modifying them by an offset. + // iterate over all vertices currently associated with the translation manipulator and update their + // positions by taking their starting positions and modifying them by an offset. template void EditorVertexSelectionBase::UpdateManipulatorsAndVerticesFromOffset( IndexedTranslationManipulator& translationManipulator, - const AZ::Vector3& localManipulatorStartPosition, const AZ::Vector3& localManipulatorOffset) + const AZ::Vector3& localManipulatorStartPosition, + const AZ::Vector3& localManipulatorOffset) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -164,22 +158,19 @@ namespace AzToolsFramework AZ::FixedVerticesRequestBus::Bind(fixedVertices, GetEntityId()); translationManipulator.Process( - [this, localManipulatorOffset, fixedVertices] - (typename IndexedTranslationManipulator::VertexLookup& vertex) - { - vertex.m_offset = AZ::AdaptVertexIn(localManipulatorOffset); + [this, localManipulatorOffset, fixedVertices](typename IndexedTranslationManipulator::VertexLookup& vertex) + { + vertex.m_offset = AZ::AdaptVertexIn(localManipulatorOffset); - bool updated = false; - const Vertex vertexPosition = vertex.m_start + vertex.m_offset; - AZ::FixedVerticesRequestBus::EventResult( - updated, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::UpdateVertex, - vertex.m_index, vertexPosition); + bool updated = false; + const Vertex vertexPosition = vertex.m_start + vertex.m_offset; + AZ::FixedVerticesRequestBus::EventResult( + updated, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::UpdateVertex, vertex.m_index, vertexPosition); - m_selectionManipulators[vertex.m_index]->SetLocalPosition(AZ::AdaptVertexOut(vertexPosition)); - }); + m_selectionManipulators[vertex.m_index]->SetLocalPosition(AZ::AdaptVertexOut(vertexPosition)); + }); - m_translationManipulator->m_manipulator.SetLocalPosition( - localManipulatorStartPosition + localManipulatorOffset); + m_translationManipulator->m_manipulator.SetLocalPosition(localManipulatorStartPosition + localManipulatorOffset); // after vertex positions have changed, anything else which relies on their positions may update if (m_onVertexPositionsUpdated) @@ -188,11 +179,10 @@ namespace AzToolsFramework } } - /// In OnMouseDown for various manipulators (linear/planar/surface), ensure we record the vertex starting position - /// for each vertex associated with the translation manipulator to use with offset calculations when updating. + // in OnMouseDown for various manipulators (linear/planar/surface), ensure we record the vertex starting position + // for each vertex associated with the translation manipulator to use with offset calculations when updating. template - void InitializeVertexLookup( - IndexedTranslationManipulator& translationManipulator, const AZ::EntityId entityId) + void InitializeVertexLookup(IndexedTranslationManipulator& translationManipulator, const AZ::EntityId entityId) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -201,29 +191,28 @@ namespace AzToolsFramework AZ::FixedVerticesRequestBus::Bind(fixedVertices, entityId); translationManipulator.Process( - [fixedVertices] - (typename IndexedTranslationManipulator::VertexLookup& vertexLookup) - { - Vertex vertex; - bool found = false; - AZ::FixedVerticesRequestBus::EventResult( - found, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::GetVertex, - vertexLookup.m_index, vertex); - - if (found) + [fixedVertices](typename IndexedTranslationManipulator::VertexLookup& vertexLookup) { - vertexLookup.m_start = vertex; - vertexLookup.m_offset = Vertex::CreateZero(); - } - }); + Vertex vertex; + bool found = false; + AZ::FixedVerticesRequestBus::EventResult( + found, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::GetVertex, vertexLookup.m_index, vertex); + + if (found) + { + vertexLookup.m_start = vertex; + vertexLookup.m_offset = Vertex::CreateZero(); + } + }); } - /// Create a translation manipulator for a specific vertex and setup its corresponding callbacks etc. + // create a translation manipulator for a specific vertex and setup its corresponding callbacks etc. template void EditorVertexSelectionBase::CreateTranslationManipulator( const AZ::EntityComponentIdPair& entityComponentIdPair, const ManipulatorManagerId managerId, - const Vertex& vertex, size_t vertexIndex) + const Vertex& vertex, + size_t vertexIndex) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -250,65 +239,65 @@ namespace AzToolsFramework // linear manipulator callbacks m_translationManipulator->m_manipulator.InstallLinearManipulatorMouseDownCallback( [this]([[maybe_unused]] const LinearManipulator::Action& action) - { - BeginBatchMovement(); - InitializeVertexLookup(*m_translationManipulator, GetEntityId()); - }); + { + BeginBatchMovement(); + InitializeVertexLookup(*m_translationManipulator, GetEntityId()); + }); m_translationManipulator->m_manipulator.InstallLinearManipulatorMouseMoveCallback( [this](const LinearManipulator::Action& action) - { - UpdateManipulatorsAndVerticesFromOffset( - *m_translationManipulator, action.m_start.m_localPosition, action.LocalPositionOffset()); - }); + { + UpdateManipulatorsAndVerticesFromOffset( + *m_translationManipulator, action.m_start.m_localPosition, action.LocalPositionOffset()); + }); m_translationManipulator->m_manipulator.InstallLinearManipulatorMouseUpCallback( [this]([[maybe_unused]] const LinearManipulator::Action& action) - { - EndBatchMovement(); - }); + { + EndBatchMovement(); + }); // planar manipulator callbacks m_translationManipulator->m_manipulator.InstallPlanarManipulatorMouseDownCallback( [this]([[maybe_unused]] const PlanarManipulator::Action& action) - { - BeginBatchMovement(); - InitializeVertexLookup(*m_translationManipulator, GetEntityId()); - }); + { + BeginBatchMovement(); + InitializeVertexLookup(*m_translationManipulator, GetEntityId()); + }); m_translationManipulator->m_manipulator.InstallPlanarManipulatorMouseMoveCallback( [this](const PlanarManipulator::Action& action) - { - UpdateManipulatorsAndVerticesFromOffset( - *m_translationManipulator, action.m_start.m_localPosition, action.LocalPositionOffset()); - }); + { + UpdateManipulatorsAndVerticesFromOffset( + *m_translationManipulator, action.m_start.m_localPosition, action.LocalPositionOffset()); + }); m_translationManipulator->m_manipulator.InstallPlanarManipulatorMouseUpCallback( [this]([[maybe_unused]] const PlanarManipulator::Action& action) - { - EndBatchMovement(); - }); + { + EndBatchMovement(); + }); // surface manipulator callbacks m_translationManipulator->m_manipulator.InstallSurfaceManipulatorMouseDownCallback( [this]([[maybe_unused]] const SurfaceManipulator::Action& action) - { - BeginBatchMovement(); - InitializeVertexLookup(*m_translationManipulator, GetEntityId()); - }); + { + BeginBatchMovement(); + InitializeVertexLookup(*m_translationManipulator, GetEntityId()); + }); m_translationManipulator->m_manipulator.InstallSurfaceManipulatorMouseMoveCallback( [this](const SurfaceManipulator::Action& action) - { - UpdateManipulatorsAndVerticesFromOffset( - *m_translationManipulator, action.m_start.m_localPosition, action.LocalPositionOffset()); - }); + { + UpdateManipulatorsAndVerticesFromOffset( + *m_translationManipulator, action.m_start.m_localPosition, action.LocalPositionOffset()); + }); m_translationManipulator->m_manipulator.InstallSurfaceManipulatorMouseUpCallback( [this]([[maybe_unused]] const SurfaceManipulator::Action& action) - { - EndBatchMovement(); - }); + { + EndBatchMovement(); + }); // register the m_translation manipulator so it appears where the selection manipulator previously was m_translationManipulator->m_manipulator.Register(managerId); @@ -330,9 +319,9 @@ namespace AzToolsFramework AZStd::transform( vertexLookups.begin(), vertexLookups.end(), AZStd::back_inserter(vertexIndices), [](const typename IndexedTranslationManipulator::VertexLookup& vertexLookup) - { - return vertexLookup.m_index; - }); + { + return vertexLookup.m_index; + }); return vertexIndices; } @@ -348,12 +337,13 @@ namespace AzToolsFramework bool m_additive = true; // is the box select adding or removing things from the selection }; - template void DoBoxSelect( - const AZ::EntityId entityId, BoxSelectData& boxSelectData, + const AZ::EntityId entityId, + BoxSelectData& boxSelectData, const ViewportInteraction::KeyboardModifiers keyboardModifiers, - const int viewportId, const EditorBoxSelect& editorBoxSelect, + const int viewportId, + const EditorBoxSelect& editorBoxSelect, const AZStd::vector>& selectionManipulators) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -384,8 +374,7 @@ namespace AzToolsFramework if (editorBoxSelect.BoxRegion()) { AZ::Transform worldFromLocal; - AZ::TransformBus::EventResult( - worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM); + AZ::TransformBus::EventResult(worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM); // bind FixedVerticesRequestBus for improved performance typename AZ::FixedVerticesRequestBus::BusPtr fixedVertices; @@ -396,8 +385,7 @@ namespace AzToolsFramework Vertex localVertex; bool found = false; AZ::FixedVerticesRequestBus::EventResult( - found, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::GetVertex, - vertexIndex, localVertex); + found, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::GetVertex, vertexIndex, localVertex); const AZ::Vector3 worldVertex = worldFromLocal.TransformPoint(AZ::AdaptVertexOut(localVertex)); const AzFramework::ScreenPoint screenPosition = GetScreenPosition(viewportId, worldVertex); @@ -406,8 +394,8 @@ namespace AzToolsFramework if (editorBoxSelect.BoxRegion()->contains(ViewportInteraction::QPointFromScreenPoint(screenPosition))) { // see if vertexIndex is in active selection - auto vertexIt = AZStd::find( - boxSelectData.m_activeSelection.begin(), boxSelectData.m_activeSelection.end(), vertexIndex); + auto vertexIt = + AZStd::find(boxSelectData.m_activeSelection.begin(), boxSelectData.m_activeSelection.end(), vertexIndex); if (!keyboardModifiers.Ctrl()) { @@ -437,8 +425,8 @@ namespace AzToolsFramework else { // not in box region - see if vertexIndex is in delta selection - auto vertexItDelta = AZStd::find( - boxSelectData.m_deltaSelection.begin(), boxSelectData.m_deltaSelection.end(), vertexIndex); + auto vertexItDelta = + AZStd::find(boxSelectData.m_deltaSelection.begin(), boxSelectData.m_deltaSelection.end(), vertexIndex); // if we find the vertex in the delta selection if (vertexItDelta != boxSelectData.m_deltaSelection.end()) @@ -451,8 +439,8 @@ namespace AzToolsFramework boxSelectData.m_deltaSelection.erase(vertexItDelta); // remove the vertex from the active selection as well - auto vertexItStart = AZStd::find( - boxSelectData.m_activeSelection.begin(), boxSelectData.m_activeSelection.end(), vertexIndex); + auto vertexItStart = + AZStd::find(boxSelectData.m_activeSelection.begin(), boxSelectData.m_activeSelection.end(), vertexIndex); if (vertexItStart != boxSelectData.m_activeSelection.end()) { @@ -467,8 +455,8 @@ namespace AzToolsFramework boxSelectData.m_deltaSelection.erase(vertexItDelta); // also add it back to the active selection - auto vertexItStart = AZStd::find( - boxSelectData.m_activeSelection.begin(), boxSelectData.m_activeSelection.end(), vertexIndex); + auto vertexItStart = + AZStd::find(boxSelectData.m_activeSelection.begin(), boxSelectData.m_activeSelection.end(), vertexIndex); if (vertexItStart == boxSelectData.m_activeSelection.end()) { @@ -491,7 +479,8 @@ namespace AzToolsFramework template void EditorVertexSelectionBase::Create( - const AZ::EntityComponentIdPair& entityComponentIdPair, const ManipulatorManagerId managerId, + const AZ::EntityComponentIdPair& entityComponentIdPair, + const ManipulatorManagerId managerId, AZStd::unique_ptr hoverSelection, const TranslationManipulators::Dimensions dimensions, const TranslationManipulatorConfiguratorFn translationManipulatorConfigurator) @@ -509,8 +498,7 @@ namespace AzToolsFramework AZ::FixedVerticesRequestBus::Bind(fixedVertices, GetEntityId()); size_t vertexCount = 0; - AZ::FixedVerticesRequestBus::EventResult( - vertexCount, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::Size); + AZ::FixedVerticesRequestBus::EventResult(vertexCount, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::Size); m_selectionManipulators.reserve(vertexCount); // initialize manipulators for all spline vertices @@ -519,12 +507,10 @@ namespace AzToolsFramework Vertex vertex; bool found = false; AZ::FixedVerticesRequestBus::EventResult( - found, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::GetVertex, - vertexIndex, vertex); + found, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::GetVertex, vertexIndex, vertex); - m_selectionManipulators.push_back(SelectionManipulator::MakeShared( - WorldFromLocalWithUniformScale(GetEntityId()), - GetNonUniformScale(GetEntityId()))); + m_selectionManipulators.push_back( + SelectionManipulator::MakeShared(WorldFromLocalWithUniformScale(GetEntityId()), GetNonUniformScale(GetEntityId()))); const auto& selectionManipulator = m_selectionManipulators.back(); selectionManipulator->Register(managerId); @@ -539,156 +525,153 @@ namespace AzToolsFramework m_editorBoxSelect.InstallLeftMouseDown( [this, vertexBoxSelectData](const ViewportInteraction::MouseInteractionEvent& /*mouseInteraction*/) - { - // grab currently selected entities (the starting selection) - vertexBoxSelectData->m_startSelection = m_translationManipulator - ? MapFromLookupsToIndices(m_translationManipulator->m_vertices) - : AZStd::vector(); + { + // grab currently selected entities (the starting selection) + vertexBoxSelectData->m_startSelection = m_translationManipulator + ? MapFromLookupsToIndices(m_translationManipulator->m_vertices) + : AZStd::vector(); - // active selection is the same as start selection on mouse down - vertexBoxSelectData->m_activeSelection = vertexBoxSelectData->m_startSelection; + // active selection is the same as start selection on mouse down + vertexBoxSelectData->m_activeSelection = vertexBoxSelectData->m_startSelection; - size_t size = 0; - AZ::FixedVerticesRequestBus::EventResult( - size, GetEntityId(), &AZ::FixedVerticesRequestBus::Handler::Size); + size_t size = 0; + AZ::FixedVerticesRequestBus::EventResult(size, GetEntityId(), &AZ::FixedVerticesRequestBus::Handler::Size); - // populate vector of all indices in container to compare against - vertexBoxSelectData->m_all.resize(size); - std::iota(vertexBoxSelectData->m_all.begin(), vertexBoxSelectData->m_all.end(), static_cast(0)); - }); + // populate vector of all indices in container to compare against + vertexBoxSelectData->m_all.resize(size); + std::iota(vertexBoxSelectData->m_all.begin(), vertexBoxSelectData->m_all.end(), static_cast(0)); + }); m_editorBoxSelect.InstallMouseMove( [this, vertexBoxSelectData](const ViewportInteraction::MouseInteractionEvent& mouseInteraction) - { - DoBoxSelect( - GetEntityId(), *vertexBoxSelectData, mouseInteraction.m_mouseInteraction.m_keyboardModifiers, - mouseInteraction.m_mouseInteraction.m_interactionId.m_viewportId, - m_editorBoxSelect, m_selectionManipulators); - }); - - m_editorBoxSelect.InstallLeftMouseUp([this, vertexBoxSelectData]() - { - if (vertexBoxSelectData->m_additive) { - // bind FixedVerticesRequestBus for improved performance - typename AZ::FixedVerticesRequestBus::BusPtr fixedVertices; - AZ::FixedVerticesRequestBus::Bind(fixedVertices, GetEntityId()); + DoBoxSelect( + GetEntityId(), *vertexBoxSelectData, mouseInteraction.m_mouseInteraction.m_keyboardModifiers, + mouseInteraction.m_mouseInteraction.m_interactionId.m_viewportId, m_editorBoxSelect, m_selectionManipulators); + }); - const AZ::EntityComponentIdPair entityComponentIdPair = m_entityComponentIdPair; - for (size_t vertexIndex : vertexBoxSelectData->m_deltaSelection) + m_editorBoxSelect.InstallLeftMouseUp( + [this, vertexBoxSelectData]() + { + if (vertexBoxSelectData->m_additive) { - Vertex vertex; - bool found = false; - AZ::FixedVerticesRequestBus::EventResult( - found, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::GetVertex, - vertexIndex, vertex); + // bind FixedVerticesRequestBus for improved performance + typename AZ::FixedVerticesRequestBus::BusPtr fixedVertices; + AZ::FixedVerticesRequestBus::Bind(fixedVertices, GetEntityId()); - // if we already have a translation manipulator, add additional vertices to it - if (m_translationManipulator) - { - // otherwise add the new selected vertex - m_translationManipulator->m_vertices.push_back( - typename IndexedTranslationManipulator::VertexLookup{ vertex, Vertex::CreateZero(), vertexIndex }); - } - else + const AZ::EntityComponentIdPair entityComponentIdPair = m_entityComponentIdPair; + for (size_t vertexIndex : vertexBoxSelectData->m_deltaSelection) { - // create a new translation manipulator if one did not already exist with the first vertex - CreateTranslationManipulator(entityComponentIdPair, m_manipulatorManagerId, vertex, vertexIndex); - // default to ensuring selection manipulators are 'selected' - m_selectionManipulators[vertexIndex]->Select(); + Vertex vertex; + bool found = false; + AZ::FixedVerticesRequestBus::EventResult( + found, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::GetVertex, vertexIndex, vertex); + + // if we already have a translation manipulator, add additional vertices to it + if (m_translationManipulator) + { + // otherwise add the new selected vertex + m_translationManipulator->m_vertices.push_back( + typename IndexedTranslationManipulator::VertexLookup{ vertex, Vertex::CreateZero(), vertexIndex }); + } + else + { + // create a new translation manipulator if one did not already exist with the first vertex + CreateTranslationManipulator(entityComponentIdPair, m_manipulatorManagerId, vertex, vertexIndex); + // default to ensuring selection manipulators are 'selected' + m_selectionManipulators[vertexIndex]->Select(); + } } } - } - else - { - // removing vertices with an active translation manipulator - if (m_translationManipulator) + else { - // iterate through all delta vertices (ones that were either - // added or removed during selection) and remove them - for (size_t vertexIndex : vertexBoxSelectData->m_deltaSelection) + // removing vertices with an active translation manipulator + if (m_translationManipulator) { - auto vertexIt = AZStd::find_if( - m_translationManipulator->m_vertices.begin(), m_translationManipulator->m_vertices.end(), - [vertexIndex](const auto& vertexLookup) - { - return vertexLookup.m_index == vertexIndex; - }); - - // remove vertex from translation manipulator - if (vertexIt != m_translationManipulator->m_vertices.end()) + // iterate through all delta vertices (ones that were either + // added or removed during selection) and remove them + for (size_t vertexIndex : vertexBoxSelectData->m_deltaSelection) { - m_translationManipulator->m_vertices.erase(vertexIt); - - // ensure it is registered to receive input and draw - if (!m_selectionManipulators[vertexIndex]->Registered()) + auto vertexIt = AZStd::find_if( + m_translationManipulator->m_vertices.begin(), m_translationManipulator->m_vertices.end(), + [vertexIndex](const auto& vertexLookup) + { + return vertexLookup.m_index == vertexIndex; + }); + + // remove vertex from translation manipulator + if (vertexIt != m_translationManipulator->m_vertices.end()) { - m_selectionManipulators[vertexIndex]->Register(m_manipulatorManagerId); + m_translationManipulator->m_vertices.erase(vertexIt); + + // ensure it is registered to receive input and draw + if (!m_selectionManipulators[vertexIndex]->Registered()) + { + m_selectionManipulators[vertexIndex]->Register(m_manipulatorManagerId); + } } } - } - // if we have no vertices left, clear selection (restore all selection - // manipulators and destroy translation manipulator) - if (m_translationManipulator->m_vertices.empty()) - { - ClearSelected(); + // if we have no vertices left, clear selection (restore all selection + // manipulators and destroy translation manipulator) + if (m_translationManipulator->m_vertices.empty()) + { + ClearSelected(); + } } } - } - // with a selection of more than one or zero, we want to ensure all selection - // manipulators are registered (can be clicked on) - if (vertexBoxSelectData->m_activeSelection.size() > 1) - { - for (size_t vertexIndex : vertexBoxSelectData->m_activeSelection) + // with a selection of more than one or zero, we want to ensure all selection + // manipulators are registered (can be clicked on) + if (vertexBoxSelectData->m_activeSelection.size() > 1) { - if (!m_selectionManipulators[vertexIndex]->Registered()) + for (size_t vertexIndex : vertexBoxSelectData->m_activeSelection) { - m_selectionManipulators[vertexIndex]->Register(m_manipulatorManagerId); + if (!m_selectionManipulators[vertexIndex]->Registered()) + { + m_selectionManipulators[vertexIndex]->Register(m_manipulatorManagerId); + } } } - } - // special case handling for only one vertex - don't want to display it when - // translation manipulator will be in exactly the same location - else if (vertexBoxSelectData->m_activeSelection.size() == 1) - { - if (vertexBoxSelectData->m_additive) - { - m_selectionManipulators[vertexBoxSelectData->m_activeSelection[0]]->Unregister(); - } - else + // special case handling for only one vertex - don't want to display it when + // translation manipulator will be in exactly the same location + else if (vertexBoxSelectData->m_activeSelection.size() == 1) { - m_selectionManipulators[vertexBoxSelectData->m_activeSelection[0]]->Register(m_manipulatorManagerId); + if (vertexBoxSelectData->m_additive) + { + m_selectionManipulators[vertexBoxSelectData->m_activeSelection[0]]->Unregister(); + } + else + { + m_selectionManipulators[vertexBoxSelectData->m_activeSelection[0]]->Register(m_manipulatorManagerId); + } } - } - // update manipulator positions (ensure translation manipulator is - // centered on current selection) - RefreshTranslationManipulator(); + // update manipulator positions (ensure translation manipulator is + // centered on current selection) + RefreshTranslationManipulator(); - // restore state once box select has completed - vertexBoxSelectData->m_startSelection.clear(); - vertexBoxSelectData->m_deltaSelection.clear(); - vertexBoxSelectData->m_activeSelection.clear(); - vertexBoxSelectData->m_all.clear(); - }); - - m_editorBoxSelect.InstallDisplayScene( - [this, vertexBoxSelectData] - (const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& /*debugDisplay*/) - { - const auto keyboardModifiers = ViewportInteraction::KeyboardModifiers( - ViewportInteraction::TranslateKeyboardModifiers(QApplication::queryKeyboardModifiers())); - - // when modifiers change ensure we refresh box selection for immediate update - if (keyboardModifiers != m_editorBoxSelect.PreviousModifiers()) - { - DoBoxSelect( - GetEntityId(), *vertexBoxSelectData, keyboardModifiers, - viewportInfo.m_viewportId, m_editorBoxSelect, m_selectionManipulators); - } - }); + // restore state once box select has completed + vertexBoxSelectData->m_startSelection.clear(); + vertexBoxSelectData->m_deltaSelection.clear(); + vertexBoxSelectData->m_activeSelection.clear(); + vertexBoxSelectData->m_all.clear(); + }); + + m_editorBoxSelect.InstallDisplayScene( + [this, vertexBoxSelectData](const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& /*debugDisplay*/) + { + const auto keyboardModifiers = ViewportInteraction::KeyboardModifiers( + ViewportInteraction::TranslateKeyboardModifiers(QApplication::queryKeyboardModifiers())); + + // when modifiers change ensure we refresh box selection for immediate update + if (keyboardModifiers != m_editorBoxSelect.PreviousModifiers()) + { + DoBoxSelect( + GetEntityId(), *vertexBoxSelectData, keyboardModifiers, viewportInfo.m_viewportId, m_editorBoxSelect, + m_selectionManipulators); + } + }); AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(GetEntityId()); AzFramework::ViewportDebugDisplayEventBus::Handler::BusConnect(GetEntityContextId()); @@ -734,12 +717,12 @@ namespace AzToolsFramework { // re-enable all selection manipulators associated with the translation // manipulator which is now being removed. - m_translationManipulator->Process([this]( - typename IndexedTranslationManipulator::VertexLookup& vertex) - { - m_selectionManipulators[vertex.m_index]->Register(m_manipulatorManagerId); - m_selectionManipulators[vertex.m_index]->Deselect(); - }); + m_translationManipulator->Process( + [this](typename IndexedTranslationManipulator::VertexLookup& vertex) + { + m_selectionManipulators[vertex.m_index]->Register(m_manipulatorManagerId); + m_selectionManipulators[vertex.m_index]->Deselect(); + }); m_translationManipulator->m_manipulator.Unregister(); m_translationManipulator.reset(); @@ -755,8 +738,7 @@ namespace AzToolsFramework template void EditorVertexSelectionBase::DisplayEntityViewport( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) + const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -767,8 +749,7 @@ namespace AzToolsFramework template void EditorVertexSelectionBase::DisplayViewport2d( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) + const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -777,8 +758,7 @@ namespace AzToolsFramework template template::value>::type*> - void EditorVertexSelectionBase::UpdateManipulatorSpace( - const AzFramework::ViewportInfo& viewportInfo) + void EditorVertexSelectionBase::UpdateManipulatorSpace(const AzFramework::ViewportInfo& viewportInfo) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -789,23 +769,19 @@ namespace AzToolsFramework &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::ShowingWorldSpace); // update the manipulator to be in the correct space if it changed - if ( m_translationManipulator - && !m_translationManipulator->m_manipulator.PerformingAction() - && worldSpace != m_worldSpace) + if (m_translationManipulator && !m_translationManipulator->m_manipulator.PerformingAction() && worldSpace != m_worldSpace) { const AZ::Transform worldFromLocal = WorldFromLocalWithUniformScale(GetEntityId()); - m_translationManipulator->m_manipulator.SetLocalOrientation(worldSpace - ? QuaternionFromTransformNoScaling(worldFromLocal).GetInverseFull() - : AZ::Quaternion::CreateIdentity()); + m_translationManipulator->m_manipulator.SetLocalOrientation( + worldSpace ? QuaternionFromTransformNoScaling(worldFromLocal).GetInverseFull() : AZ::Quaternion::CreateIdentity()); m_worldSpace = worldSpace; } } template template::value>::type*> - void EditorVertexSelectionBase::UpdateManipulatorSpace( - const AzFramework::ViewportInfo& /*viewportInfo*/) const + void EditorVertexSelectionBase::UpdateManipulatorSpace(const AzFramework::ViewportInfo& /*viewportInfo*/) const { } @@ -813,8 +789,7 @@ namespace AzToolsFramework static bool CanDeleteSelection(const AZ::EntityId entityId, const int64_t selectedCount) { size_t vertexCount = 0; - AZ::VariableVerticesRequestBus::EventResult( - vertexCount, entityId, &AZ::VariableVerticesRequestBus::Handler::Size); + AZ::VariableVerticesRequestBus::EventResult(vertexCount, entityId, &AZ::VariableVerticesRequestBus::Handler::Size); // prevent deleting all vertices const int64_t remaining = aznumeric_cast(vertexCount) - selectedCount; @@ -825,9 +800,8 @@ namespace AzToolsFramework void EditorVertexSelectionVariable::ShowVertexDeletionWarning() { QMessageBox::information( - AzToolsFramework::GetActiveWindow(), "Information", - "It is not possible to delete all vertices.", - QMessageBox::Ok, QMessageBox::NoButton); + AzToolsFramework::GetActiveWindow(), "Information", "It is not possible to delete all vertices.", QMessageBox::Ok, + QMessageBox::NoButton); } template @@ -856,19 +830,19 @@ namespace AzToolsFramework EditorVertexSelectionBase::m_translationManipulator; // ensure we remove vertices in reverse order - std::sort(translationManipulator->m_vertices.rbegin(), translationManipulator->m_vertices.rend(), + std::sort( + translationManipulator->m_vertices.rbegin(), translationManipulator->m_vertices.rend(), [](const typename IndexedTranslationManipulator::VertexLookup& lhs, - const typename IndexedTranslationManipulator::VertexLookup& rhs) - { - return lhs.m_index < rhs.m_index; - }); + const typename IndexedTranslationManipulator::VertexLookup& rhs) + { + return lhs.m_index < rhs.m_index; + }); - translationManipulator->Process([this]( - typename IndexedTranslationManipulator::VertexLookup& vertex) - { - SafeRemoveVertex( - EditorVertexSelectionBase::GetEntityComponentIdPair(), vertex.m_index); - }); + translationManipulator->Process( + [this](typename IndexedTranslationManipulator::VertexLookup& vertex) + { + SafeRemoveVertex(EditorVertexSelectionBase::GetEntityComponentIdPair(), vertex.m_index); + }); translationManipulator->m_manipulator.Unregister(); translationManipulator.reset(); @@ -876,8 +850,7 @@ namespace AzToolsFramework if (EditorVertexSelectionBase::m_hoverSelection) { - EditorVertexSelectionBase::m_hoverSelection->Register( - EditorVertexSelectionBase::GetManipulatorManagerId()); + EditorVertexSelectionBase::m_hoverSelection->Register(EditorVertexSelectionBase::GetManipulatorManagerId()); } EditorVertexSelectionBase::SetState(EditorVertexSelectionBase::State::Selecting); @@ -895,11 +868,9 @@ namespace AzToolsFramework InitializeVertexLookup(*m_translationManipulator, GetEntityId()); // note: AdaptVertexIn/Out is to ensure we clamp the vertex local Z position to 0 if // dealing with Vector2s when setting the position of the manipulator. - const AZ::Vector3 localOffset = - localPosition - m_translationManipulator->m_manipulator.GetLocalTransform().GetTranslation(); + const AZ::Vector3 localOffset = localPosition - m_translationManipulator->m_manipulator.GetLocalTransform().GetTranslation(); UpdateManipulatorsAndVerticesFromOffset( - *m_translationManipulator, - AZ::AdaptVertexOut(AZ::AdaptVertexIn(localPosition)), + *m_translationManipulator, AZ::AdaptVertexOut(AZ::AdaptVertexIn(localPosition)), AZ::AdaptVertexOut(AZ::AdaptVertexIn(localOffset))); RefreshTranslationManipulator(); @@ -928,23 +899,20 @@ namespace AzToolsFramework // calculate average position of selected vertices for translation manipulator MidpointCalculator midpointCalculator; m_translationManipulator->Process( - [this, &midpointCalculator, fixedVertices] - (typename IndexedTranslationManipulator::VertexLookup& vertex) - { - Vertex v; - bool found = false; - AZ::FixedVerticesRequestBus::EventResult( - found, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::GetVertex, - vertex.m_index, v); - - if (found) + [this, &midpointCalculator, fixedVertices](typename IndexedTranslationManipulator::VertexLookup& vertex) { - midpointCalculator.AddPosition(AZ::AdaptVertexOut(v)); - } - }); + Vertex v; + bool found = false; + AZ::FixedVerticesRequestBus::EventResult( + found, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::GetVertex, vertex.m_index, v); + + if (found) + { + midpointCalculator.AddPosition(AZ::AdaptVertexOut(v)); + } + }); - m_translationManipulator->m_manipulator.SetLocalPosition( - AZ::AdaptVertexOut(midpointCalculator.CalculateMidpoint())); + m_translationManipulator->m_manipulator.SetLocalPosition(AZ::AdaptVertexOut(midpointCalculator.CalculateMidpoint())); } } @@ -970,8 +938,7 @@ namespace AzToolsFramework Vertex vertex; bool found = false; AZ::FixedVerticesRequestBus::EventResult( - found, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::GetVertex, - manipulatorIndex, vertex); + found, fixedVertices, &AZ::FixedVerticesRequestBus::Handler::GetVertex, manipulatorIndex, vertex); if (found) { @@ -1037,39 +1004,41 @@ namespace AzToolsFramework } } - /// Handle correctly selecting/deselecting vertices in a vertex selection. + // handle correctly selecting/deselecting vertices in a vertex selection. template void EditorVertexSelectionBase::SelectionManipulatorSelectCallback( - const size_t vertexIndex, const ViewportInteraction::MouseInteraction& interaction, - const AZ::EntityComponentIdPair& entityComponentIdPair, const ManipulatorManagerId managerId) + const size_t vertexIndex, + const ViewportInteraction::MouseInteraction& interaction, + const AZ::EntityComponentIdPair& entityComponentIdPair, + const ManipulatorManagerId managerId) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); Vertex vertex; bool found = false; AZ::FixedVerticesRequestBus::EventResult( - found, GetEntityId(), &AZ::FixedVerticesRequestBus::Handler::GetVertex, - vertexIndex, vertex); + found, GetEntityId(), &AZ::FixedVerticesRequestBus::Handler::GetVertex, vertexIndex, vertex); if (m_translationManipulator != nullptr && interaction.m_keyboardModifiers.Ctrl()) { // ensure all selection manipulators are enabled when selecting more than one (the first // will have been disabled when only selecting an individual vertex - m_translationManipulator->Process([this, managerId]( - typename IndexedTranslationManipulator::VertexLookup& vertexLookup) - { - m_selectionManipulators[vertexLookup.m_index]->Register(managerId); - }); + m_translationManipulator->Process( + [this, managerId](typename IndexedTranslationManipulator::VertexLookup& vertexLookup) + { + m_selectionManipulators[vertexLookup.m_index]->Register(managerId); + }); // if selection manipulator was selected, find it in the vector of vertices stored in // the translation manipulator and remove it if (m_selectionManipulators[vertexIndex]->Selected()) { - auto it = AZStd::find_if(m_translationManipulator->m_vertices.begin(), m_translationManipulator->m_vertices.end(), + auto it = AZStd::find_if( + m_translationManipulator->m_vertices.begin(), m_translationManipulator->m_vertices.end(), [vertexIndex](const typename IndexedTranslationManipulator::VertexLookup vertexLookup) - { - return vertexIndex == vertexLookup.m_index; - }); + { + return vertexIndex == vertexLookup.m_index; + }); if (it != m_translationManipulator->m_vertices.end()) { @@ -1099,28 +1068,27 @@ namespace AzToolsFramework { // if one does not already exist, or we're not holding shift, create a new translation // manipulator at this vertex - CreateTranslationManipulator( - entityComponentIdPair, managerId, vertex, vertexIndex); + CreateTranslationManipulator(entityComponentIdPair, managerId, vertex, vertexIndex); } } - /// Configure the selection manipulator for fixed editor selection - this configures the view and action - /// of interacting with the selection manipulator. Vertices can just be selected (create a translation - /// manipulator) but not added or removed. + // configure the selection manipulator for fixed editor selection - this configures the view and action + // of interacting with the selection manipulator. Vertices can just be selected (create a translation + // manipulator) but not added or removed. template void EditorVertexSelectionFixed::SetupSelectionManipulator( const AZStd::shared_ptr& selectionManipulator, const AZ::EntityComponentIdPair& entityComponentIdPair, - const ManipulatorManagerId managerId, const size_t vertexIndex) + const ManipulatorManagerId managerId, + const size_t vertexIndex) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); // setup selection manipulator - const AZStd::shared_ptr selectionView = - AzToolsFramework::CreateManipulatorViewSphere(AZ::Color(1.0f, 0.0f, 0.0f, 1.0f), - g_defaultManipulatorSphereRadius, [&selectionManipulator] - (const ViewportInteraction::MouseInteraction& /*mouseInteraction*/, - const bool mouseOver, const AZ::Color& defaultColor) + const AZStd::shared_ptr selectionView = AzToolsFramework::CreateManipulatorViewSphere( + AZ::Color(1.0f, 0.0f, 0.0f, 1.0f), g_defaultManipulatorSphereRadius, + [&selectionManipulator]( + const ViewportInteraction::MouseInteraction& /*mouseInteraction*/, const bool mouseOver, const AZ::Color& defaultColor) { if (selectionManipulator->Selected()) { @@ -1128,72 +1096,68 @@ namespace AzToolsFramework } const float opacity[2] = { 0.5f, 1.0f }; - return AZ::Color( - defaultColor.GetR(), defaultColor.GetG(), defaultColor.GetB(), opacity[mouseOver]); + return AZ::Color(defaultColor.GetR(), defaultColor.GetG(), defaultColor.GetB(), opacity[mouseOver]); }); - selectionManipulator->SetViews(ManipulatorViews{selectionView}); + selectionManipulator->SetViews(ManipulatorViews{ selectionView }); - selectionManipulator->InstallLeftMouseUpCallback([ - this, entityComponentIdPair, vertexIndex, managerId]( - const ViewportInteraction::MouseInteraction& interaction) - { - EditorVertexSelectionBase::SelectionManipulatorSelectCallback( - vertexIndex, interaction, entityComponentIdPair, managerId); - }); + selectionManipulator->InstallLeftMouseUpCallback( + [this, entityComponentIdPair, vertexIndex, managerId](const ViewportInteraction::MouseInteraction& interaction) + { + EditorVertexSelectionBase::SelectionManipulatorSelectCallback( + vertexIndex, interaction, entityComponentIdPair, managerId); + }); } - /// Configure the selection manipulator for variable editor selection - this configures the view and action - /// of interacting with the selection manipulator. In this case, hovering the mouse with a modifier key held - /// will indicate removal, and clicking with a modifier key will remove the vertex. + // configure the selection manipulator for variable editor selection - this configures the view and action + // of interacting with the selection manipulator. In this case, hovering the mouse with a modifier key held + // will indicate removal, and clicking with a modifier key will remove the vertex. template void EditorVertexSelectionVariable::SetupSelectionManipulator( const AZStd::shared_ptr& selectionManipulator, const AZ::EntityComponentIdPair& entityComponentIdPair, - const ManipulatorManagerId managerId, const size_t vertexIndex) + const ManipulatorManagerId managerId, + const size_t vertexIndex) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); // setup selection manipulator - const AZStd::shared_ptr manipulatorView = - AzToolsFramework::CreateManipulatorViewSphere(AZ::Color(1.0f, 0.0f, 0.0f, 1.0f), - g_defaultManipulatorSphereRadius, [&selectionManipulator] - (const ViewportInteraction::MouseInteraction& mouseInteraction, - const bool mouseOver, const AZ::Color& defaultColor) + const AZStd::shared_ptr manipulatorView = AzToolsFramework::CreateManipulatorViewSphere( + AZ::Color(1.0f, 0.0f, 0.0f, 1.0f), g_defaultManipulatorSphereRadius, + [&selectionManipulator]( + const ViewportInteraction::MouseInteraction& mouseInteraction, const bool mouseOver, const AZ::Color& defaultColor) + { + if (mouseInteraction.m_keyboardModifiers.Alt() && mouseOver) { - if (mouseInteraction.m_keyboardModifiers.Alt() && mouseOver) - { - // indicate removal of manipulator - return AZ::Color(0.5f, 0.5f, 0.5f, 0.5f); - } - - // highlight or not if mouse is over - const float opacity[2] = { 0.5f, 1.0f }; - if (selectionManipulator->Selected()) - { - return AZ::Color(1.0f, 1.0f, 0.0f, opacity[mouseOver]); - } + // indicate removal of manipulator + return AZ::Color(0.5f, 0.5f, 0.5f, 0.5f); + } - return AZ::Color( - defaultColor.GetR(), defaultColor.GetG(), defaultColor.GetB(), opacity[mouseOver]); - }); + // highlight or not if mouse is over + const float opacity[2] = { 0.5f, 1.0f }; + if (selectionManipulator->Selected()) + { + return AZ::Color(1.0f, 1.0f, 0.0f, opacity[mouseOver]); + } + return AZ::Color(defaultColor.GetR(), defaultColor.GetG(), defaultColor.GetB(), opacity[mouseOver]); + }); - selectionManipulator->SetViews(ManipulatorViews{manipulatorView}); + selectionManipulator->SetViews(ManipulatorViews{ manipulatorView }); selectionManipulator->InstallLeftMouseUpCallback( [this, entityComponentIdPair, vertexIndex, managerId](const ViewportInteraction::MouseInteraction& interaction) - { - if (interaction.m_keyboardModifiers.Alt()) - { - SafeRemoveVertex(entityComponentIdPair, vertexIndex); - } - else { - EditorVertexSelectionBase::SelectionManipulatorSelectCallback( - vertexIndex, interaction, entityComponentIdPair, managerId); - } - }); + if (interaction.m_keyboardModifiers.Alt()) + { + SafeRemoveVertex(entityComponentIdPair, vertexIndex); + } + else + { + EditorVertexSelectionBase::SelectionManipulatorSelectCallback( + vertexIndex, interaction, entityComponentIdPair, managerId); + } + }); } template @@ -1240,15 +1204,17 @@ namespace AzToolsFramework template void EditorVertexSelectionFixed::PrepareActions() { - ActionOverride backAction = CreateBackAction("Deselect Vertex", "Deselect current vertex selection", [this]() - { - EditorVertexSelectionBase::ClearSelected(); - }); + ActionOverride backAction = CreateBackAction( + "Deselect Vertex", "Deselect current vertex selection", + [this]() + { + EditorVertexSelectionBase::ClearSelected(); + }); backAction.SetEntityComponentIdPair(EditorVertexSelectionBase::GetEntityComponentIdPair()); - EditorVertexSelectionBase::m_actionOverrides[static_cast( - EditorVertexSelectionBase::State::Translating)] = AZStd::vector { backAction }; + EditorVertexSelectionBase::m_actionOverrides[static_cast(EditorVertexSelectionBase::State::Translating)] = + AZStd::vector{ backAction }; } template @@ -1261,12 +1227,13 @@ namespace AzToolsFramework MidpointCalculator midpointCalculator; // sort in descending order - std::sort(manipulators.rbegin(), manipulators.rend(), + std::sort( + manipulators.rbegin(), manipulators.rend(), [](const typename IndexedTranslationManipulator::VertexLookup& lhs, const typename IndexedTranslationManipulator::VertexLookup& rhs) - { - return lhs.m_index < rhs.m_index; - }); + { + return lhs.m_index < rhs.m_index; + }); // iterate over current selection for (size_t manipulatorIndex = 0; manipulatorIndex < manipulators.size(); ++manipulatorIndex) @@ -1313,8 +1280,7 @@ namespace AzToolsFramework // create translation manipulator for duplicated vertices at new position EditorVertexSelectionBase::CreateTranslationManipulator( - EditorVertexSelectionBase::GetEntityComponentIdPair(), - EditorVertexSelectionBase::GetManipulatorManagerId(), + EditorVertexSelectionBase::GetEntityComponentIdPair(), EditorVertexSelectionBase::GetManipulatorManagerId(), localCenterPosition, vertices[0].m_index); // clear all selection manipulators to default unselected state @@ -1337,47 +1303,46 @@ namespace AzToolsFramework template void EditorVertexSelectionVariable::PrepareActions() { - ActionOverride deleteAction = CreateDeleteAction(s_deleteVerticesTitle, s_duplicateVerticesDesc, [this]() - { - DestroySelected(); - }); + ActionOverride deleteAction = CreateDeleteAction( + s_deleteVerticesTitle, s_duplicateVerticesDesc, + [this]() + { + DestroySelected(); + }); const AZ::EntityComponentIdPair entityComponentIdPair( - EditorVertexSelectionBase::GetEntityId(), - EditorVertexSelectionBase::GetComponentId()); + EditorVertexSelectionBase::GetEntityId(), EditorVertexSelectionBase::GetComponentId()); // note: important to register which entity/component id pair this action is associated with deleteAction.SetEntityComponentIdPair(entityComponentIdPair); - ActionOverride deselectAction = CreateBackAction(s_deselectVerticesTitle, s_deselectVerticesDesc, [this]() - { - EditorVertexSelectionBase::ClearSelected(); - }); + ActionOverride deselectAction = CreateBackAction( + s_deselectVerticesTitle, s_deselectVerticesDesc, + [this]() + { + EditorVertexSelectionBase::ClearSelected(); + }); // note: important to register which entity/component id pair this action is associated with deselectAction.SetEntityComponentIdPair(entityComponentIdPair); EditorVertexSelectionBase::m_actionOverrides[static_cast(EditorVertexSelectionBase::State::Translating)] = - AZStd::vector - { - ActionOverride() - .SetUri(AzToolsFramework::s_duplicateAction) - .SetKeySequence(QKeySequence(Qt::CTRL + Qt::Key_D)) - .SetTitle(s_duplicateVerticesTitle) - .SetTip(s_duplicateVerticesDesc) - .SetCallback([this]() - { - DuplicateSelected(); - }) - .SetEntityComponentIdPair(entityComponentIdPair), - deleteAction, - deselectAction - }; + AZStd::vector{ ActionOverride() + .SetUri(AzToolsFramework::s_duplicateAction) + .SetKeySequence(QKeySequence(Qt::CTRL + Qt::Key_D)) + .SetTitle(s_duplicateVerticesTitle) + .SetTip(s_duplicateVerticesDesc) + .SetCallback( + [this]() + { + DuplicateSelected(); + }) + .SetEntityComponentIdPair(entityComponentIdPair), + deleteAction, deselectAction }; } template - void InsertVertexAfter( - const AZ::EntityComponentIdPair& entityComponentIdPair, const size_t vertexIndex, const Vertex& localPosition) + void InsertVertexAfter(const AZ::EntityComponentIdPair& entityComponentIdPair, const size_t vertexIndex, const Vertex& localPosition) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -1389,15 +1354,13 @@ namespace AzToolsFramework if (insertPosition >= size) { AZ::VariableVerticesRequestBus::Event( - entityComponentIdPair.GetEntityId(), &AZ::VariableVerticesRequestBus::Handler::AddVertex, - localPosition); + entityComponentIdPair.GetEntityId(), &AZ::VariableVerticesRequestBus::Handler::AddVertex, localPosition); } else { bool updated = false; AZ::VariableVerticesRequestBus::EventResult( - updated, entityComponentIdPair.GetEntityId(), - &AZ::VariableVerticesRequestBus::Handler::InsertVertex, + updated, entityComponentIdPair.GetEntityId(), &AZ::VariableVerticesRequestBus::Handler::InsertVertex, insertPosition, localPosition); } @@ -1409,21 +1372,16 @@ namespace AzToolsFramework { bool removed = false; AZ::VariableVerticesRequestBus::EventResult( - removed, entityComponentIdPair.GetEntityId(), - &AZ::VariableVerticesRequestBus::Handler::RemoveVertex, vertexIndex); + removed, entityComponentIdPair.GetEntityId(), &AZ::VariableVerticesRequestBus::Handler::RemoveVertex, vertexIndex); RefreshUiAfterAddRemove(entityComponentIdPair); } // explicit instantiations - template void InsertVertexAfter( - const AZ::EntityComponentIdPair& entityComponentIdPair, size_t, const AZ::Vector2&); - template void InsertVertexAfter( - const AZ::EntityComponentIdPair& entityComponentIdPair, size_t, const AZ::Vector3&); - template void SafeRemoveVertex( - const AZ::EntityComponentIdPair& entityComponentIdPair, size_t vertexIndex); - template void SafeRemoveVertex( - const AZ::EntityComponentIdPair& entityComponentIdPair, size_t vertexIndex); + template void InsertVertexAfter(const AZ::EntityComponentIdPair& entityComponentIdPair, size_t, const AZ::Vector2&); + template void InsertVertexAfter(const AZ::EntityComponentIdPair& entityComponentIdPair, size_t, const AZ::Vector3&); + template void SafeRemoveVertex(const AZ::EntityComponentIdPair& entityComponentIdPair, size_t vertexIndex); + template void SafeRemoveVertex(const AZ::EntityComponentIdPair& entityComponentIdPair, size_t vertexIndex); AZ_CLASS_ALLOCATOR_IMPL_TEMPLATE(EditorVertexSelectionFixed, AZ::SystemAllocator, 0) AZ_CLASS_ALLOCATOR_IMPL_TEMPLATE(EditorVertexSelectionFixed, AZ::SystemAllocator, 0) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.h index 4d1c3ce43f..0036ea42d4 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.h @@ -1,22 +1,22 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once #include #include #include -#include #include +#include #include #include #include @@ -24,37 +24,74 @@ namespace AzToolsFramework { - /// Concrete implementation of AZ::VariableVertices backed by an AZ::VertexContainer. + //! Concrete implementation of AZ::VariableVertices backed by an AZ::VertexContainer. template - class VariableVerticesVertexContainer - : public AZ::VariableVertices + class VariableVerticesVertexContainer : public AZ::VariableVertices { public: explicit VariableVerticesVertexContainer(AZ::VertexContainer& vertexContainer) - : m_vertexContainer(vertexContainer) {} - - bool GetVertex(size_t index, Vertex& vertex) const override { return m_vertexContainer.GetVertex(index, vertex); } - bool UpdateVertex(size_t index, const Vertex& vertex) override { return m_vertexContainer.UpdateVertex(index, vertex); }; - void AddVertex(const Vertex& vertex) override { m_vertexContainer.AddVertex(vertex); } - bool InsertVertex(size_t index, const Vertex& vertex) override { return m_vertexContainer.InsertVertex(index, vertex); } - bool RemoveVertex(size_t index) override { return m_vertexContainer.RemoveVertex(index); } - void SetVertices(const AZStd::vector& vertices) override { m_vertexContainer.SetVertices(vertices); }; - void ClearVertices() override { m_vertexContainer.Clear(); } - size_t Size() const override { return m_vertexContainer.Size(); } - bool Empty() const override { return m_vertexContainer.Empty(); } + : m_vertexContainer(vertexContainer) + { + } + + bool GetVertex(size_t index, Vertex& vertex) const override + { + return m_vertexContainer.GetVertex(index, vertex); + } + + bool UpdateVertex(size_t index, const Vertex& vertex) override + { + return m_vertexContainer.UpdateVertex(index, vertex); + }; + + void AddVertex(const Vertex& vertex) override + { + m_vertexContainer.AddVertex(vertex); + } + + bool InsertVertex(size_t index, const Vertex& vertex) override + { + return m_vertexContainer.InsertVertex(index, vertex); + } + + bool RemoveVertex(size_t index) override + { + return m_vertexContainer.RemoveVertex(index); + } + + void SetVertices(const AZStd::vector& vertices) override + { + m_vertexContainer.SetVertices(vertices); + }; + + void ClearVertices() override + { + m_vertexContainer.Clear(); + } + + size_t Size() const override + { + return m_vertexContainer.Size(); + } + + bool Empty() const override + { + return m_vertexContainer.Empty(); + } private: AZ::VertexContainer& m_vertexContainer; }; - /// Concrete implementation of AZ::FixedVertices backed by an AZStd::array. + //! Concrete implementation of AZ::FixedVertices backed by an AZStd::array. template - class FixedVerticesArray - : public AZ::FixedVertices + class FixedVerticesArray : public AZ::FixedVertices { public: explicit FixedVerticesArray(AZStd::array& array) - : m_array(array) {} + : m_array(array) + { + } bool GetVertex(size_t index, Vertex& vertex) const override { @@ -72,22 +109,26 @@ namespace AzToolsFramework if (index < m_array.size()) { m_array[index] = vertex; - return true;; + return true; + ; } return false; } - size_t Size() const override { return m_array.size(); } + size_t Size() const override + { + return m_array.size(); + } private: AZStd::array& m_array; }; - /// EditorVertexSelection provides an interface for a collection of manipulators to expose - /// editing of vertices in a container/collection. EditorVertexSelection is templated on the - /// type of Vertex (Vector2/Vector3) stored in the container. - /// EditorVertexSelectionBase provides common behavior shared across Fixed and Variable selections. + //! EditorVertexSelection provides an interface for a collection of manipulators to expose + //! editing of vertices in a container/collection. EditorVertexSelection is templated on the + //! type of Vertex (Vector2/Vector3) stored in the container. + //! EditorVertexSelectionBase provides common behavior shared across Fixed and Variable selections. template class EditorVertexSelectionBase : private AzFramework::EntityDebugDisplayEventBus::Handler @@ -99,89 +140,110 @@ namespace AzToolsFramework EditorVertexSelectionBase& operator=(EditorVertexSelectionBase&&) = default; virtual ~EditorVertexSelectionBase() = default; - /// Setup and configure the EditorVertexSelection for operation. + //! Setup and configure the EditorVertexSelection for operation. void Create( - const AZ::EntityComponentIdPair& entityComponentIdPair, ManipulatorManagerId managerId, + const AZ::EntityComponentIdPair& entityComponentIdPair, + ManipulatorManagerId managerId, AZStd::unique_ptr hoverSelection, TranslationManipulators::Dimensions dimensions, TranslationManipulatorConfiguratorFn translationManipulatorConfigurator); - /// Create a translation manipulator for a given vertex. + //! Create a translation manipulator for a given vertex. void CreateTranslationManipulator( - const AZ::EntityComponentIdPair& entityComponentIdPair, - ManipulatorManagerId managerId, const Vertex& vertex, size_t index); + const AZ::EntityComponentIdPair& entityComponentIdPair, ManipulatorManagerId managerId, const Vertex& vertex, size_t index); - /// Destroy all manipulators associated with the vertex selection. + //! Destroy all manipulators associated with the vertex selection. void Destroy(); - /// Set custom callback for when vertex positions are updated. + //! Set custom callback for when vertex positions are updated. void SetVertexPositionsUpdatedCallback(const AZStd::function& callback); - /// Update manipulators based on local changes to vertex positions. + //! Update manipulators based on local changes to vertex positions. void RefreshLocal(); - /// Update the translation manipulator to be correctly positioned based - /// on the current selection (recenter it). + //! Update the translation manipulator to be correctly positioned based + //! on the current selection (recenter it). void RefreshTranslationManipulator(); - /// Update manipulators based on changes to the entity's transform and non-uniform scale. + //! Update manipulators based on changes to the entity's transform and non-uniform scale. void RefreshSpace(const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale = AZ::Vector3::CreateOne()); - /// Set bounds dirty (need recalculating) for all owned manipulators (selection, translation, hover). + //! Set bounds dirty (need recalculating) for all owned manipulators (selection, translation, hover). void SetBoundsDirty(); - /// How should the EditorVertexSelection respond to mouse input. - virtual bool HandleMouse( - const ViewportInteraction::MouseInteractionEvent& mouseInteraction); + //! How should the EditorVertexSelection respond to mouse input. + virtual bool HandleMouse(const ViewportInteraction::MouseInteractionEvent& mouseInteraction); - /// Snap the selected vertices to the terrain. - /// Note: With a multi-selection the manipulator will be translated to the picked - /// terrain position with all verts moved relative to it. - void SnapVerticesToTerrain( - const ViewportInteraction::MouseInteractionEvent& mouseInteraction); + //! Snap the selected vertices to the terrain. + //! Note: With a multi-selection the manipulator will be translated to the picked + //! terrain position with all vertices moved relative to it. + void SnapVerticesToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction); - /// The Actions provided by the EditorVertexSelection while it is active. - /// e.g. Vertex deletion, duplication etc. + //! The Actions provided by the EditorVertexSelection while it is active. + //! e.g. Vertex deletion, duplication etc. AZStd::vector ActionOverrides() const; - /// Let the EditorVertexSelection know a batch movement is about to begin so it - /// can avoid certain unnecessary updates. + //! Let the EditorVertexSelection know a batch movement is about to begin so it + //! can avoid certain unnecessary updates. void BeginBatchMovement(); - /// Let the EditorVertexSelection know a batch movement has ended so it can return - /// to its normal state. + //! Let the EditorVertexSelection know a batch movement has ended so it can return + //! to its normal state. void EndBatchMovement(); - /// Set the position of the TranslationManipulators (if active). + //! Set the position of the TranslationManipulators (if active). void SetSelectedPosition(const AZ::Vector3& localPosition); - AZ::EntityId GetEntityId() const { return m_entityComponentIdPair.GetEntityId(); } + AZ::EntityId GetEntityId() const + { + return m_entityComponentIdPair.GetEntityId(); + } protected: - /// Internal interface for EditorVertexSelection. + //! Internal interface for EditorVertexSelection. virtual void SetupSelectionManipulator( const AZStd::shared_ptr& selectionManipulator, const AZ::EntityComponentIdPair& entityComponentIdPair, - ManipulatorManagerId managerId, size_t index) = 0; + ManipulatorManagerId managerId, + size_t index) = 0; virtual void PrepareActions() = 0; - /// Default behavior when clicking on a selection manipulator (representing a vertex). + //! Default behavior when clicking on a selection manipulator (representing a vertex). void SelectionManipulatorSelectCallback( - size_t index, const ViewportInteraction::MouseInteraction& interaction, - const AZ::EntityComponentIdPair& entityComponentIdPair, ManipulatorManagerId managerId); + size_t index, + const ViewportInteraction::MouseInteraction& interaction, + const AZ::EntityComponentIdPair& entityComponentIdPair, + ManipulatorManagerId managerId); - /// Destroy the translation manipulator and deselect all vertices. + //! Destroy the translation manipulator and deselect all vertices. void ClearSelected(); - AZ::ComponentId GetComponentId() const { return m_entityComponentIdPair.GetComponentId(); } - const AZ::EntityComponentIdPair& GetEntityComponentIdPair() const { return m_entityComponentIdPair; } - ManipulatorManagerId GetManipulatorManagerId() const { return m_manipulatorManagerId; } + AZ::ComponentId GetComponentId() const + { + return m_entityComponentIdPair.GetComponentId(); + } - /// Is the translation vertex manipulator in 2D or 3D. - TranslationManipulators::Dimensions Dimensions() const { return m_dimensions; } + const AZ::EntityComponentIdPair& GetEntityComponentIdPair() const + { + return m_entityComponentIdPair; + } - /// How to configure the translation manipulator (view and axes). - TranslationManipulatorConfiguratorFn ConfiguratorFn() const { return m_manipulatorConfiguratorFn; } + ManipulatorManagerId GetManipulatorManagerId() const + { + return m_manipulatorManagerId; + } + + //! Is the translation vertex manipulator in 2D or 3D. + TranslationManipulators::Dimensions Dimensions() const + { + return m_dimensions; + } + + //! How to configure the translation manipulator (view and axes). + TranslationManipulatorConfiguratorFn ConfiguratorFn() const + { + return m_manipulatorConfiguratorFn; + } - /// The state we are in when editing vertices. + //! The state we are in when editing vertices. enum class State { Selecting, @@ -190,23 +252,22 @@ namespace AzToolsFramework void SetState(State state); - AZStd::unique_ptr m_hoverSelection = nullptr; ///< Interface to hover selection, representing bounds that can be selected. - AZStd::shared_ptr> m_translationManipulator = nullptr; ///< Manipulator when vertex is selected to translate it. - AZStd::vector> m_selectionManipulators; ///< Manipulators for each vertex when entity is selected. - AZStd::array, 2> m_actionOverrides; ///< Available actions corresponding to each mode. + AZStd::unique_ptr m_hoverSelection = + nullptr; //!< Interface to hover selection, representing bounds that can be selected. + AZStd::shared_ptr> m_translationManipulator = + nullptr; //!< Manipulator when vertex is selected to translate it. + AZStd::vector> + m_selectionManipulators; //!< Manipulators for each vertex when entity is selected. + AZStd::array, 2> m_actionOverrides; //!< Available actions corresponding to each mode. private: // AzFramework::EntityDebugDisplayEventBus - void DisplayEntityViewport( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) override; + void DisplayEntityViewport(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override; // AzFramework::ViewportDebugDisplayEventBus - void DisplayViewport2d( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) override; + void DisplayViewport2d(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override; - /// Set selected manipulator and vertices position from offset from starting position when pressed. + //! Set selected manipulator and vertices position from offset from starting position when pressed. void UpdateManipulatorsAndVerticesFromOffset( IndexedTranslationManipulator& translationManipulator, const AZ::Vector3& localManipulatorStartPosition, @@ -217,23 +278,24 @@ namespace AzToolsFramework template::value>::type* = nullptr> void UpdateManipulatorSpace(const AzFramework::ViewportInfo& viewportInfo) const; - EditorBoxSelect m_editorBoxSelect; ///< Provide box select support for vertex selection. - AZ::EntityComponentIdPair m_entityComponentIdPair; ///< Id of the Entity and Component this editor vertex selection was created on. - ManipulatorManagerId m_manipulatorManagerId; ///< Id of the manager manipulators created from this type will be associated with. - TranslationManipulators::Dimensions m_dimensions = TranslationManipulators::Dimensions::Three; ///< The dimensions this vertex selection was created with. - TranslationManipulatorConfiguratorFn m_manipulatorConfiguratorFn = nullptr; ///< Function pointer set on Create to decide look and functionality of translation manipulator. - AZStd::function m_onVertexPositionsUpdated = nullptr; ///< Callback for when vertex positions are changed. - State m_state = State::Selecting; ///< Different states VertexSelection can be in. - bool m_worldSpace = false; ///< Are the manipulators being used in local or world space. - bool m_batchMovementInProgress = false; ///< If a batch movement operation is in progress we do not want to - ///< refresh the VertexSelection during it for performance reasons. + EditorBoxSelect m_editorBoxSelect; //!< Provide box select support for vertex selection. + AZ::EntityComponentIdPair m_entityComponentIdPair; //!< Id of the Entity and Component this editor vertex selection was created on. + ManipulatorManagerId m_manipulatorManagerId; //!< Id of the manager manipulators created from this type will be associated with. + TranslationManipulators::Dimensions m_dimensions = + TranslationManipulators::Dimensions::Three; //!< The dimensions this vertex selection was created with. + TranslationManipulatorConfiguratorFn m_manipulatorConfiguratorFn = + nullptr; //!< Function pointer set on Create to decide look and functionality of translation manipulator. + AZStd::function m_onVertexPositionsUpdated = nullptr; //!< Callback for when vertex positions are changed. + State m_state = State::Selecting; //!< Different states VertexSelection can be in. + bool m_worldSpace = false; //!< Are the manipulators being used in local or world space. + bool m_batchMovementInProgress = false; //!< If a batch movement operation is in progress we do not want to + //!< refresh the VertexSelection during it for performance reasons. }; - /// EditorVertexSelectionFixed provides selection and editing for a fixed length number of - /// vertices. New vertices cannot be inserted/added or removed. + //! EditorVertexSelectionFixed provides selection and editing for a fixed length number of + //! vertices. New vertices cannot be inserted/added or removed. template - class EditorVertexSelectionFixed - : public EditorVertexSelectionBase + class EditorVertexSelectionFixed : public EditorVertexSelectionBase { public: AZ_CLASS_ALLOCATOR_DECL @@ -247,15 +309,15 @@ namespace AzToolsFramework void SetupSelectionManipulator( const AZStd::shared_ptr& selectionManipulator, const AZ::EntityComponentIdPair& entityComponentIdPair, - ManipulatorManagerId managerId, size_t index) override; + ManipulatorManagerId managerId, + size_t index) override; void PrepareActions() override; }; - /// EditorVertexSelectionVariable provides selection and editing for a variable length number of - /// vertices. New vertices can be inserted/added or removed from the collection. + //! EditorVertexSelectionVariable provides selection and editing for a variable length number of + //! vertices. New vertices can be inserted/added or removed from the collection. template - class EditorVertexSelectionVariable - : public EditorVertexSelectionBase + class EditorVertexSelectionVariable : public EditorVertexSelectionBase { public: AZ_CLASS_ALLOCATOR_DECL @@ -272,7 +334,8 @@ namespace AzToolsFramework void SetupSelectionManipulator( const AZStd::shared_ptr& selectionManipulator, const AZ::EntityComponentIdPair& entityComponentIdPair, - ManipulatorManagerId managerId, size_t vertIndex) override; + ManipulatorManagerId managerId, + size_t vertIndex) override; //! Presents a warning to the user that vertices will not be deleted. //! @note Allow overriding by derived classes to make this a noop if required. @@ -281,21 +344,18 @@ namespace AzToolsFramework private: void PrepareActions() override; - /// @return The center point of the selected vertices. - Vertex InsertSelectedInPlace( - AZStd::vector::VertexLookup>& manipulators); + //! @return The center point of the selected vertices. + Vertex InsertSelectedInPlace(AZStd::vector::VertexLookup>& manipulators); }; - /// Helper for inserting a vertex in a variable vertices container. + //! Helper for inserting a vertex in a variable vertices container. template - void InsertVertexAfter( - const AZ::EntityComponentIdPair& entityComponentIdPair, size_t vertIndex, const Vertex& localPosition); + void InsertVertexAfter(const AZ::EntityComponentIdPair& entityComponentIdPair, size_t vertIndex, const Vertex& localPosition); - /// Helper for removing a vertex in a variable vertices container. - /// Remove a vertex from the container and ensure the associated manipulator is unset and - /// property display values are refreshed. + //! Helper for removing a vertex in a variable vertices container. + //! Remove a vertex from the container and ensure the associated manipulator is unset and + //! property display values are refreshed. template - void SafeRemoveVertex( - const AZ::EntityComponentIdPair& entityComponentIdPair, size_t vertexIndex); + void SafeRemoveVertex(const AZ::EntityComponentIdPair& entityComponentIdPair, size_t vertexIndex); } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/HoverSelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/HoverSelection.h index c5f58f0d56..a389237b2b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/HoverSelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/HoverSelection.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -16,10 +16,10 @@ namespace AzToolsFramework { - /// HoverSelection provides an interface for manipulator/s offering selection when - /// the mouse is hovered over a particular bound. This interface is used to represent - /// a Spline manipulator bound, and a series of LineSegment manipulator bounds. - /// This generic interface allows EditorVertexSelection to use either Spline or LineSegment selection. + //! HoverSelection provides an interface for manipulator/s offering selection when + //! the mouse is hovered over a particular bound. This interface is used to represent + //! a Spline manipulator bound, and a series of LineSegment manipulator bounds. + //! This generic interface allows EditorVertexSelection to use either Spline or LineSegment selection. class HoverSelection { public: @@ -33,21 +33,37 @@ namespace AzToolsFramework virtual void SetNonUniformScale(const AZ::Vector3& nonUniformScale) = 0; }; - /// NullHoverSelection is used when vertices cannot be inserted. This serves as a no-op - /// and is used to prevent the need for additional null checks in EditorVertexSelection. - class NullHoverSelection - : public HoverSelection + //! NullHoverSelection is used when vertices cannot be inserted. This serves as a no-op + //! and is used to prevent the need for additional null checks in EditorVertexSelection. + class NullHoverSelection : public HoverSelection { public: NullHoverSelection() = default; NullHoverSelection(const NullHoverSelection&) = delete; NullHoverSelection& operator=(const NullHoverSelection&) = delete; - void Register(ManipulatorManagerId /*managerId*/) override {} - void Unregister() override {} - void SetBoundsDirty() override {} - void Refresh() override {} - void SetSpace(const AZ::Transform& /*worldFromLocal*/) override {} - void SetNonUniformScale([[maybe_unused]] const AZ::Vector3& nonUniformScale) override {} + void Register([[maybe_unused]] ManipulatorManagerId managerId) override + { + } + + void Unregister() override + { + } + + void SetBoundsDirty() override + { + } + + void Refresh() override + { + } + + void SetSpace([[maybe_unused]] const AZ::Transform& worldFromLocal) override + { + } + + void SetNonUniformScale([[maybe_unused]] const AZ::Vector3& nonUniformScale) override + { + } }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineHoverSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineHoverSelection.cpp index e26c154be9..12d5f399c3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineHoverSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineHoverSelection.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "LineHoverSelection.h" @@ -22,17 +22,15 @@ namespace AzToolsFramework { - static const AZ::Color s_lineSelectManipulatorColor = AZ::Color(0.0f, 1.0f, 0.0f, 1.0f); + static const AZ::Color LineSelectManipulatorColor = AZ::Color(0.0f, 1.0f, 0.0f, 1.0f); template - static void UpdateLineSegmentPosition( - const size_t vertIndex, const AZ::EntityId entityId, LineSegmentSelectionManipulator& lineSegment) + static void UpdateLineSegmentPosition(const size_t vertIndex, const AZ::EntityId entityId, LineSegmentSelectionManipulator& lineSegment) { Vertex start; bool foundStart = false; AZ::FixedVerticesRequestBus::EventResult( - foundStart, entityId, &AZ::FixedVerticesRequestBus::Handler::GetVertex, - vertIndex, start); + foundStart, entityId, &AZ::FixedVerticesRequestBus::Handler::GetVertex, vertIndex, start); if (foundStart) { @@ -40,14 +38,12 @@ namespace AzToolsFramework } size_t size = 0; - AZ::FixedVerticesRequestBus::EventResult( - size, entityId, &AZ::FixedVerticesRequestBus::Handler::Size); + AZ::FixedVerticesRequestBus::EventResult(size, entityId, &AZ::FixedVerticesRequestBus::Handler::Size); Vertex end; bool foundEnd = false; AZ::FixedVerticesRequestBus::EventResult( - foundEnd, entityId, &AZ::FixedVerticesRequestBus::Handler::GetVertex, - (vertIndex + 1) % size, end); + foundEnd, entityId, &AZ::FixedVerticesRequestBus::Handler::GetVertex, (vertIndex + 1) % size, end); if (foundEnd) { @@ -56,8 +52,7 @@ namespace AzToolsFramework // update the view const float lineWidth = 0.05f; - lineSegment.SetView( - CreateManipulatorViewLineSelect(lineSegment, s_lineSelectManipulatorColor, lineWidth)); + lineSegment.SetView(CreateManipulatorViewLineSelect(lineSegment, LineSelectManipulatorColor, lineWidth)); } template @@ -66,9 +61,8 @@ namespace AzToolsFramework : m_entityId(entityComponentIdPair.GetEntityId()) { // create a line segment manipulator from vertex positions and setup its callback - auto setupLineSegment = [this] ( - const AZ::EntityComponentIdPair& entityComponentIdPair, - const ManipulatorManagerId managerId, const size_t vertIndex) + auto setupLineSegment = + [this](const AZ::EntityComponentIdPair& entityComponentIdPair, const ManipulatorManagerId managerId, const size_t vertIndex) { m_lineSegmentManipulators.push_back(LineSegmentSelectionManipulator::MakeShared()); AZStd::shared_ptr& lineSegmentManipulator = m_lineSegmentManipulators.back(); @@ -81,11 +75,9 @@ namespace AzToolsFramework lineSegmentManipulator->InstallLeftMouseUpCallback( [vertIndex, entityComponentIdPair](const LineSegmentSelectionManipulator::Action& action) - { - InsertVertexAfter( - entityComponentIdPair, vertIndex, - AZ::AdaptVertexIn(action.m_localLineHitPosition)); - }); + { + InsertVertexAfter(entityComponentIdPair, vertIndex, AZ::AdaptVertexIn(action.m_localLineHitPosition)); + }); }; // create all line segment manipulators for the polygon prism (used for selection bounds) @@ -150,8 +142,7 @@ namespace AzToolsFramework void LineSegmentHoverSelection::Refresh() { size_t vertexCount = 0; - AZ::FixedVerticesRequestBus::EventResult( - vertexCount, m_entityId, &AZ::FixedVerticesRequestBus::Handler::Size); + AZ::FixedVerticesRequestBus::EventResult(vertexCount, m_entityId, &AZ::FixedVerticesRequestBus::Handler::Size); // update the start/end positions of all the line segment manipulators to ensure // they stay consistent with the polygon prism shape diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineHoverSelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineHoverSelection.h index eb5e3991c5..e14930f9ca 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineHoverSelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineHoverSelection.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -25,17 +25,14 @@ namespace AzToolsFramework { class LineSegmentSelectionManipulator; - /// LineSegmentHoverSelection is a concrete implementation of HoverSelection wrapping a collection/container - /// of vertices and a list of LineSegmentManipulators. The underlying manipulators are used to control selection - /// by highlighting where on the line a new vertex will be inserted. + //! LineSegmentHoverSelection is a concrete implementation of HoverSelection wrapping a collection/container + //! of vertices and a list of LineSegmentManipulators. The underlying manipulators are used to control selection + //! by highlighting where on the line a new vertex will be inserted. template - class LineSegmentHoverSelection - : public HoverSelection + class LineSegmentHoverSelection : public HoverSelection { public: - explicit LineSegmentHoverSelection( - const AZ::EntityComponentIdPair& entityComponentIdPair, - ManipulatorManagerId managerId); + explicit LineSegmentHoverSelection(const AZ::EntityComponentIdPair& entityComponentIdPair, ManipulatorManagerId managerId); LineSegmentHoverSelection(const LineSegmentHoverSelection&) = delete; LineSegmentHoverSelection& operator=(const LineSegmentHoverSelection&) = delete; ~LineSegmentHoverSelection(); @@ -49,6 +46,6 @@ namespace AzToolsFramework private: AZ::EntityId m_entityId; - AZStd::vector> m_lineSegmentManipulators; ///< Manipulators for each line. + AZStd::vector> m_lineSegmentManipulators; //!< Manipulators for each line. }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineSegmentSelectionManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineSegmentSelectionManipulator.cpp index 8874e0dcd9..45f2803818 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineSegmentSelectionManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineSegmentSelectionManipulator.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "LineSegmentSelectionManipulator.h" @@ -20,15 +20,20 @@ namespace AzToolsFramework { LineSegmentSelectionManipulator::Action CalculateManipulationDataAction( - const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Vector3& rayOrigin, - const AZ::Vector3& rayDirection, const float rayLength, const AZ::Vector3& localStart, const AZ::Vector3& localEnd) + const AZ::Transform& worldFromLocal, + const AZ::Vector3& nonUniformScale, + const AZ::Vector3& rayOrigin, + const AZ::Vector3& rayDirection, + const float rayLength, + const AZ::Vector3& localStart, + const AZ::Vector3& localEnd) { AZ::Vector3 worldClosestPositionRay, worldClosestPositionLineSegment; float rayProportion, lineSegmentProportion; AZ::Intersect::ClosestSegmentSegment( - rayOrigin, rayOrigin + rayDirection * rayLength, - worldFromLocal.TransformPoint(nonUniformScale * localStart), worldFromLocal.TransformPoint(nonUniformScale * localEnd), - rayProportion, lineSegmentProportion, worldClosestPositionRay, worldClosestPositionLineSegment); + rayOrigin, rayOrigin + rayDirection * rayLength, worldFromLocal.TransformPoint(nonUniformScale * localStart), + worldFromLocal.TransformPoint(nonUniformScale * localEnd), rayProportion, lineSegmentProportion, worldClosestPositionRay, + worldClosestPositionLineSegment); AZ::Transform worldFromLocalNormalized = worldFromLocal; const AZ::Vector3 scale = worldFromLocalNormalized.ExtractUniformScale() * nonUniformScale; @@ -47,7 +52,9 @@ namespace AzToolsFramework AttachLeftMouseDownImpl(); } - LineSegmentSelectionManipulator::~LineSegmentSelectionManipulator() {} + LineSegmentSelectionManipulator::~LineSegmentSelectionManipulator() + { + } void LineSegmentSelectionManipulator::InstallLeftMouseDownCallback(const MouseActionCallback& onMouseDownCallback) { @@ -112,12 +119,9 @@ namespace AzToolsFramework if (mouseInteraction.m_keyboardModifiers.Ctrl() && !mouseInteraction.m_keyboardModifiers.Shift()) { m_manipulatorView->Draw( - GetManipulatorManagerId(), managerState, - GetManipulatorId(), { - TransformUniformScale(GetSpace()), GetNonUniformScale(), - m_localStart, MouseOver() - }, - debugDisplay, cameraState, mouseInteraction); + GetManipulatorManagerId(), managerState, GetManipulatorId(), + { TransformUniformScale(GetSpace()), GetNonUniformScale(), m_localStart, MouseOver() }, debugDisplay, cameraState, + mouseInteraction); } } @@ -135,4 +139,4 @@ namespace AzToolsFramework { m_manipulatorView->Invalidate(GetManipulatorManagerId()); } -} +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineSegmentSelectionManipulator.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineSegmentSelectionManipulator.h index d9e317c378..107a0ccf9f 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineSegmentSelectionManipulator.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineSegmentSelectionManipulator.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -20,12 +20,12 @@ namespace AzToolsFramework { class ManipulatorView; - /// A manipulator to expose where on a line a user is moving their mouse. + //! A manipulator to expose where on a line a user is moving their mouse. class LineSegmentSelectionManipulator : public BaseManipulator , public ManipulatorSpace { - /// Private constructor. + //! Private constructor. LineSegmentSelectionManipulator(); public: @@ -37,10 +37,10 @@ namespace AzToolsFramework ~LineSegmentSelectionManipulator(); - /// A Manipulator must only be created and managed through a shared_ptr. + //! A Manipulator must only be created and managed through a shared_ptr. static AZStd::shared_ptr MakeShared(); - /// Mouse action data used by MouseActionCallback. + //! Mouse action data used by MouseActionCallback. struct Action { AZ::Vector3 m_localLineHitPosition; @@ -57,18 +57,31 @@ namespace AzToolsFramework const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) override; - void SetStart(const AZ::Vector3& startLocal) { m_localStart = startLocal; } - void SetEnd(const AZ::Vector3& endLocal) { m_localEnd = endLocal; } - const AZ::Vector3& GetStart() const { return m_localStart; } - const AZ::Vector3& GetEnd() const { return m_localEnd; } + void SetStart(const AZ::Vector3& startLocal) + { + m_localStart = startLocal; + } + + void SetEnd(const AZ::Vector3& endLocal) + { + m_localEnd = endLocal; + } + + const AZ::Vector3& GetStart() const + { + return m_localStart; + } + + const AZ::Vector3& GetEnd() const + { + return m_localEnd; + } void SetView(AZStd::unique_ptr&& view); private: - void OnLeftMouseDownImpl( - const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; - void OnLeftMouseUpImpl( - const ViewportInteraction::MouseInteraction& interaction) override; + void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; + void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override; void InvalidateImpl() override; void SetBoundsDirtyImpl() override; @@ -79,12 +92,18 @@ namespace AzToolsFramework MouseActionCallback m_onLeftMouseDownCallback = nullptr; MouseActionCallback m_onLeftMouseUpCallback = nullptr; - ViewportInteraction::KeyboardModifiers m_keyboardModifiers; ///< What modifier keys are pressed when interacting with this manipulator. + ViewportInteraction::KeyboardModifiers + m_keyboardModifiers; //!< What modifier keys are pressed when interacting with this manipulator. - AZStd::unique_ptr m_manipulatorView = nullptr; ///< Look of manipulator. + AZStd::unique_ptr m_manipulatorView = nullptr; //!< Look of manipulator. }; LineSegmentSelectionManipulator::Action CalculateManipulationDataAction( - const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Vector3& rayOrigin, - const AZ::Vector3& rayDirection, float rayLength, const AZ::Vector3& localStart, const AZ::Vector3& localEnd); + const AZ::Transform& worldFromLocal, + const AZ::Vector3& nonUniformScale, + const AZ::Vector3& rayOrigin, + const AZ::Vector3& rayDirection, + float rayLength, + const AZ::Vector3& localStart, + const AZ::Vector3& localEnd); } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.cpp index 34ae28bd13..604e74b6f5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "LinearManipulator.h" @@ -22,13 +22,16 @@ namespace AzToolsFramework { LinearManipulator::Starter CalculateLinearManipulationDataStart( - const LinearManipulator::Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, - const AZ::Transform& localTransform, const ViewportInteraction::MouseInteraction& interaction, const float intersectionDistance, + const LinearManipulator::Fixed& fixed, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& nonUniformScale, + const AZ::Transform& localTransform, + const ViewportInteraction::MouseInteraction& interaction, + const float intersectionDistance, const AzFramework::CameraState& cameraState) { - const ManipulatorInteraction manipulatorInteraction = - BuildManipulatorInteraction( - worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection); + const ManipulatorInteraction manipulatorInteraction = BuildManipulatorInteraction( + worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection); const AZ::Vector3 axis = TransformDirectionNoScaling(localTransform, fixed.m_axis); const AZ::Vector3 rayCrossAxis = manipulatorInteraction.m_localRayDirection.Cross(axis); @@ -47,32 +50,35 @@ namespace AzToolsFramework manipulatorInteraction.m_localRayOrigin + manipulatorInteraction.m_localRayDirection * intersectionDistance; Internal::CalculateRayPlaneIntersectingPoint( - manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection, - localIntersectionPoint, startTransition.m_localNormal, start.m_localHitPosition); + manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection, localIntersectionPoint, + startTransition.m_localNormal, start.m_localHitPosition); start.m_screenPosition = interaction.m_mousePick.m_screenCoordinates; start.m_localPosition = localTransform.GetTranslation(); - start.m_localScale = AZ::Vector3(localTransform.GetUniformScale());; + start.m_localScale = AZ::Vector3(localTransform.GetUniformScale()); + ; start.m_localAxis = axis; // sign to determine which side of the linear axis we pressed // (useful to know when the visual axis flips to face the camera) - start.m_sign = - AZ::GetSign((start.m_localHitPosition - localTransform.GetTranslation()).Dot(axis)); + start.m_sign = AZ::GetSign((start.m_localHitPosition - localTransform.GetTranslation()).Dot(axis)); startTransition.m_screenToWorldScale = 1.0f / CalculateScreenToWorldMultiplier((worldFromLocal * localTransform).GetTranslation(), cameraState); - return {startTransition, start}; + return { startTransition, start }; } LinearManipulator::Action CalculateLinearManipulationDataAction( - const LinearManipulator::Fixed& fixed, const LinearManipulator::Starter& starter, - const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Transform& localTransform, - const GridSnapParameters& gridSnapParams, const ViewportInteraction::MouseInteraction& interaction) + const LinearManipulator::Fixed& fixed, + const LinearManipulator::Starter& starter, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& nonUniformScale, + const AZ::Transform& localTransform, + const GridSnapParameters& gridSnapParams, + const ViewportInteraction::MouseInteraction& interaction) { - const ManipulatorInteraction manipulatorInteraction = - BuildManipulatorInteraction( - worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection); + const ManipulatorInteraction manipulatorInteraction = BuildManipulatorInteraction( + worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection); const auto& [startTransition, start] = starter; @@ -81,8 +87,8 @@ namespace AzToolsFramework // if an invalid ray intersection is attempted AZ::Vector3 localHitPosition = start.m_localHitPosition; Internal::CalculateRayPlaneIntersectingPoint( - manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection, - start.m_localHitPosition, startTransition.m_localNormal, localHitPosition); + manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection, start.m_localHitPosition, + startTransition.m_localNormal, localHitPosition); localHitPosition = Internal::TryConstrainHitPositionToView( localHitPosition, start.m_localHitPosition, worldFromLocal.GetInverse(), @@ -103,9 +109,8 @@ namespace AzToolsFramework LinearManipulator::Action action; action.m_fixed = fixed; action.m_start = start; - action.m_current.m_localPositionOffset = snapping - ? CalculateSnappedAmount(unsnappedOffset, axis, gridSize * scaleRecip) - : unsnappedOffset; + action.m_current.m_localPositionOffset = + snapping ? CalculateSnappedAmount(unsnappedOffset, axis, gridSize * scaleRecip) : unsnappedOffset; action.m_current.m_screenPosition = interaction.m_mousePick.m_screenCoordinates; action.m_viewportId = interaction.m_interactionId.m_viewportId; @@ -191,7 +196,8 @@ namespace AzToolsFramework // note: m_localTransform must not be made uniform as it may contain a local scale we want to snap m_onLeftMouseUpCallback(CalculateLinearManipulationDataAction( - m_fixed, m_starter, TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalTransform(), gridSnapParams, interaction)); + m_fixed, m_starter, TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalTransform(), gridSnapParams, + interaction)); } } @@ -202,16 +208,14 @@ namespace AzToolsFramework const ViewportInteraction::MouseInteraction& mouseInteraction) { const AZ::Transform localTransform = m_useVisualsOverride - ? AZ::Transform::CreateFromQuaternionAndTranslation( - m_visualOrientationOverride, GetLocalPosition()) + ? AZ::Transform::CreateFromQuaternionAndTranslation(m_visualOrientationOverride, GetLocalPosition()) : GetLocalTransform(); if (cl_manipulatorDrawDebug) { if (PerformingAction()) { - const GridSnapParameters gridSnapParams = - GridSnapSettings(mouseInteraction.m_interactionId.m_viewportId); + const GridSnapParameters gridSnapParams = GridSnapSettings(mouseInteraction.m_interactionId.m_viewportId); const auto action = CalculateLinearManipulationDataAction( m_fixed, m_starter, TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalTransform(), gridSnapParams, @@ -219,9 +223,10 @@ namespace AzToolsFramework // display the exact hit (ray intersection) of the mouse pick on the manipulator DrawTransformAxes( - debugDisplay, TransformUniformScale(GetSpace()) * - AZ::Transform::CreateTranslation( - action.m_start.m_localHitPosition + GetNonUniformScale() * action.m_current.m_localPositionOffset)); + debugDisplay, + TransformUniformScale(GetSpace()) * + AZ::Transform::CreateTranslation( + action.m_start.m_localHitPosition + GetNonUniformScale() * action.m_current.m_localPositionOffset)); } AZ::Transform combined = GetLocalTransform(); @@ -229,8 +234,7 @@ namespace AzToolsFramework combined = GetSpace() * combined; DrawTransformAxes(debugDisplay, combined); - DrawAxis( - debugDisplay, combined.GetTranslation(), TransformDirectionNoScaling(combined, m_fixed.m_axis)); + DrawAxis(debugDisplay, combined.GetTranslation(), TransformDirectionNoScaling(combined, m_fixed.m_axis)); } for (auto& view : m_manipulatorViews) @@ -238,12 +242,9 @@ namespace AzToolsFramework auto nonUniformScale = GetNonUniformScale(); view->Draw( - GetManipulatorManagerId(), managerState, - GetManipulatorId(), { - ApplySpace(localTransform), GetNonUniformScale(), - AZ::Vector3::CreateZero(), MouseOver() - }, - debugDisplay, cameraState, mouseInteraction); + GetManipulatorManagerId(), managerState, GetManipulatorId(), + { ApplySpace(localTransform), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, cameraState, + mouseInteraction); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.h index c3d43a2535..240d4c7b9b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -22,13 +22,13 @@ namespace AzToolsFramework { struct GridSnapParameters; - /// LinearManipulator serves as a visual tool for users to modify values - /// in one dimension on an axis defined in 3D space. + //! LinearManipulator serves as a visual tool for users to modify values + //! in one dimension on an axis defined in 3D space. class LinearManipulator : public BaseManipulator , public ManipulatorSpaceWithLocalTransform { - /// Private constructor. + //! Private constructor. explicit LinearManipulator(const AZ::Transform& worldFromLocal); public: @@ -41,68 +41,80 @@ namespace AzToolsFramework ~LinearManipulator() = default; - /// A Manipulator must only be created and managed through a shared_ptr. - /// @note worldFromLocal should not contain scale. + //! A Manipulator must only be created and managed through a shared_ptr. + //! @note worldFromLocal should not contain scale. static AZStd::shared_ptr MakeShared(const AZ::Transform& worldFromLocal); - /// Unchanging data set once for the linear manipulator. + //! Unchanging data set once for the linear manipulator. struct Fixed { - AZ::Vector3 m_axis = AZ::Vector3::CreateAxisX(); ///< The axis the manipulator will move along. + AZ::Vector3 m_axis = AZ::Vector3::CreateAxisX(); //!< The axis the manipulator will move along. }; - /// Data passed between the initial press and first movement of the linear manipulator. + //! Data passed between the initial press and first movement of the linear manipulator. struct StartTransition { - /// The normal in local space of the manipulator when the mouse down event happens. + //! The normal in local space of the manipulator when the mouse down event happens. AZ::Vector3 m_localNormal; - /// Used to scale movement based on camera distance if we want screen space instead - /// of world space displacement. + //! Used to scale movement based on camera distance if we want screen space instead + //! of world space displacement. float m_screenToWorldScale; }; - /// The state of the manipulator at the start of an interaction. + //! The state of the manipulator at the start of an interaction. struct Start { - AZ::Vector3 m_localPosition; ///< The current position of the manipulator in local space. - AZ::Vector3 m_localScale; ///< The current scale of the manipulator in local space. - AZ::Vector3 m_localHitPosition; ///< The intersection point in local space between the ray and the manipulator when the mouse down event happens. - AZ::Vector3 m_localAxis; ///< The axis in the local space of the manipulator itself. - float m_sign; ///< Used to determine which side of the axis we clicked on in case it's flipped to face the camera. - AzFramework::ScreenPoint m_screenPosition; ///< The initial position in screen space of the manipulator. + AZ::Vector3 m_localPosition; //!< The current position of the manipulator in local space. + AZ::Vector3 m_localScale; //!< The current scale of the manipulator in local space. + AZ::Vector3 m_localHitPosition; //!< The intersection point in local space between the ray and the manipulator when the mouse + //!< down event happens. + AZ::Vector3 m_localAxis; //!< The axis in the local space of the manipulator itself. + float m_sign; //!< Used to determine which side of the axis we clicked on in case it's flipped to face the camera. + AzFramework::ScreenPoint m_screenPosition; //!< The initial position in screen space of the manipulator. }; - /// The state of the manipulator during an interaction. + //! The state of the manipulator during an interaction. struct Current { - AZ::Vector3 m_localPositionOffset; ///< The current offset of the manipulator from its starting position in local space. - AZ::Vector3 m_localScaleOffset; ///< The current offset of the manipulator from its starting scale in local space. - AzFramework::ScreenPoint m_screenPosition; ///< The current position in screen space of the manipulator. + AZ::Vector3 m_localPositionOffset; //!< The current offset of the manipulator from its starting position in local space. + AZ::Vector3 m_localScaleOffset; //!< The current offset of the manipulator from its starting scale in local space. + AzFramework::ScreenPoint m_screenPosition; //!< The current position in screen space of the manipulator. }; - /// Mouse action data used by MouseActionCallback (wraps Fixed, Start and Current manipulator state). + //! Mouse action data used by MouseActionCallback (wraps Fixed, Start and Current manipulator state). struct Action { Fixed m_fixed; Start m_start; Current m_current; ViewportInteraction::KeyboardModifiers m_modifiers; - int m_viewportId; ///< The id of the viewport this manipulator is being used in. - AZ::Vector3 LocalScale() const { return m_start.m_localScale + m_current.m_localScaleOffset; } - AZ::Vector3 LocalScaleOffset() const { return m_current.m_localScaleOffset; } - AZ::Vector3 LocalPosition() const { return m_start.m_localPosition + m_current.m_localPositionOffset; } - AZ::Vector3 LocalPositionOffset() const { return m_current.m_localPositionOffset; } + int m_viewportId; //!< The id of the viewport this manipulator is being used in. + AZ::Vector3 LocalScale() const + { + return m_start.m_localScale + m_current.m_localScaleOffset; + } + AZ::Vector3 LocalScaleOffset() const + { + return m_current.m_localScaleOffset; + } + AZ::Vector3 LocalPosition() const + { + return m_start.m_localPosition + m_current.m_localPositionOffset; + } + AZ::Vector3 LocalPositionOffset() const + { + return m_current.m_localPositionOffset; + } AZ::Vector2 ScreenOffset() const { - return AzFramework::Vector2FromScreenVector( - m_current.m_screenPosition - m_start.m_screenPosition); + return AzFramework::Vector2FromScreenVector(m_current.m_screenPosition - m_start.m_screenPosition); } }; - /// This is the function signature of callbacks that will be invoked whenever a manipulator - /// is clicked on or dragged. + //! This is the function signature of callbacks that will be invoked whenever a manipulator + //! is clicked on or dragged. using MouseActionCallback = AZStd::function; - /// Tuple of StartTransition (initial mouse down to mouse move) and Start state. + //! Tuple of StartTransition (initial mouse down to mouse move) and Start state. using Starter = AZStd::tuple; void InstallLeftMouseDownCallback(const MouseActionCallback& onMouseDownCallback); @@ -116,7 +128,10 @@ namespace AzToolsFramework const ViewportInteraction::MouseInteraction& mouseInteraction) override; void SetAxis(const AZ::Vector3& axis); - const AZ::Vector3& GetAxis() const { return m_fixed.m_axis; } + const AZ::Vector3& GetAxis() const + { + return m_fixed.m_axis; + } template void SetViews(Views&& views) @@ -135,12 +150,9 @@ namespace AzToolsFramework } private: - void OnLeftMouseDownImpl( - const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; - void OnLeftMouseUpImpl( - const ViewportInteraction::MouseInteraction& interaction) override; - void OnMouseMoveImpl( - const ViewportInteraction::MouseInteraction& interaction) override; + void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; + void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override; + void OnMouseMoveImpl(const ViewportInteraction::MouseInteraction& interaction) override; void InvalidateImpl() override; void SetBoundsDirtyImpl() override; @@ -155,16 +167,24 @@ namespace AzToolsFramework MouseActionCallback m_onLeftMouseUpCallback = nullptr; MouseActionCallback m_onMouseMoveCallback = nullptr; - ManipulatorViews m_manipulatorViews; ///< Look of manipulator. + ManipulatorViews m_manipulatorViews; //!< Look of manipulator. }; LinearManipulator::Starter CalculateLinearManipulationDataStart( - const LinearManipulator::Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, - const AZ::Transform& localTransform, const ViewportInteraction::MouseInteraction& interaction, float intersectionDistance, + const LinearManipulator::Fixed& fixed, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& nonUniformScale, + const AZ::Transform& localTransform, + const ViewportInteraction::MouseInteraction& interaction, + float intersectionDistance, const AzFramework::CameraState& cameraState); LinearManipulator::Action CalculateLinearManipulationDataAction( - const LinearManipulator::Fixed& fixed, const LinearManipulator::Starter& starter, - const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Transform& localTransform, - const GridSnapParameters& gridSnapParams, const ViewportInteraction::MouseInteraction& interaction); + const LinearManipulator::Fixed& fixed, + const LinearManipulator::Starter& starter, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& nonUniformScale, + const AZ::Transform& localTransform, + const GridSnapParameters& gridSnapParams, + const ViewportInteraction::MouseInteraction& interaction); } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorBus.h index 7768368d6b..a79a14abc2 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorBus.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -26,56 +26,55 @@ namespace AzToolsFramework using ManipulatorManagerId = IdType; static const ManipulatorManagerId InvalidManipulatorManagerId = ManipulatorManagerId(0); - /// EBus interface used to send requests to ManipulatorManager. - class ManipulatorManagerRequests - : public AZ::EBusTraits + //! EBus interface used to send requests to ManipulatorManager. + class ManipulatorManagerRequests : public AZ::EBusTraits { public: - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; /**< We can have multiple manipulator managers. - In the case where there are multiple viewports, each displaying - a different set of entities, a different manipulator manager is required - to provide a different collision space for each viewport so that mouse - hit detection can be handled properly. */ + //! We can have multiple manipulator managers. + //! In the case where there are multiple viewports, each displaying + //! a different set of entities, a different manipulator manager is required + //! to provide a different collision space for each viewport so that mouse + //! hit detection can be handled properly. + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; using BusIdType = ManipulatorManagerId; static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; virtual ~ManipulatorManagerRequests() = default; - /// Register a manipulator with the Manipulator Manager. - /// @param manipulator The manipulator parameter is passed as a shared_ptr so - /// that the system responsible for managing manipulators can maintain ownership - /// of the manipulator even if is destroyed while in use. + //! Register a manipulator with the Manipulator Manager. + //! @param manipulator The manipulator parameter is passed as a shared_ptr so + //! that the system responsible for managing manipulators can maintain ownership + //! of the manipulator even if is destroyed while in use. virtual void RegisterManipulator(AZStd::shared_ptr manipulator) = 0; - /// Unregister a manipulator from the Manipulator Manager. - /// After unregistering the manipulator, it will be excluded from mouse hit detection - /// and will not receive any mouse action events. The Manipulator Manager will also - /// relinquish ownership of the manipulator. + //! Unregister a manipulator from the Manipulator Manager. + //! After unregistering the manipulator, it will be excluded from mouse hit detection + //! and will not receive any mouse action events. The Manipulator Manager will also + //! relinquish ownership of the manipulator. virtual void UnregisterManipulator(BaseManipulator* manipulator) = 0; - /// Delete a manipulator bound. + //! Delete a manipulator bound. virtual void DeleteManipulatorBound(Picking::RegisteredBoundId boundId) = 0; - /// Mark the bound of a manipulator dirty so it's excluded from mouse hit detection. - /// This should be called whenever a manipulator is moved. + //! Mark the bound of a manipulator dirty so it's excluded from mouse hit detection. + //! This should be called whenever a manipulator is moved. virtual void SetBoundDirty(Picking::RegisteredBoundId boundId) = 0; - /// Returns true if the manipulator manager is currently interacting, otherwise false. + //! Returns true if the manipulator manager is currently interacting, otherwise false. virtual bool Interacting() const = 0; - /// Update the bound for a manipulator. - /// If \ref boundId hasn't been registered before or it's invalid, a new bound is created and set using \ref boundShapeData - /// @param manipulatorId The id of the manipulator whose bound needs to update. - /// @param boundId The id of the bound that needs to update. - /// @param boundShapeData The pointer to the new bound shape data. - /// @return If \ref boundId has been registered return the same id, otherwise create a new bound and return its id. + //! Update the bound for a manipulator. + //! If \ref boundId hasn't been registered before or it's invalid, a new bound is created and set using \ref boundShapeData. + //! @param manipulatorId The id of the manipulator whose bound needs to update. + //! @param boundId The id of the bound that needs to update. + //! @param boundShapeData The pointer to the new bound shape data. + //! @return If \ref boundId has been registered return the same id, otherwise create a new bound and return its id. virtual Picking::RegisteredBoundId UpdateBound( - ManipulatorId manipulatorId, Picking::RegisteredBoundId boundId, - const Picking::BoundRequestShapeBase& boundShapeData) = 0; + ManipulatorId manipulatorId, Picking::RegisteredBoundId boundId, const Picking::BoundRequestShapeBase& boundShapeData) = 0; }; - /// Type to inherit to implement ManipulatorManagerRequests. + //! Type to inherit to implement ManipulatorManagerRequests. using ManipulatorManagerRequestBus = AZ::EBus; -}//namespace AzToolsFramework +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorManager.cpp index c856c5f9a8..3a6a2487c3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorManager.cpp @@ -1,17 +1,17 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ -#include "BaseManipulator.h" #include "ManipulatorManager.h" +#include "BaseManipulator.h" #include #include @@ -51,7 +51,8 @@ namespace AzToolsFramework if (manipulator->Registered()) { - AZ_Assert(manipulator->GetManipulatorManagerId() == m_manipulatorManagerId, + AZ_Assert( + manipulator->GetManipulatorManagerId() == m_manipulatorManagerId, "This manipulator was registered with a different manipulator manager!"); return; } @@ -75,8 +76,7 @@ namespace AzToolsFramework } Picking::RegisteredBoundId ManipulatorManager::UpdateBound( - const ManipulatorId manipulatorId, const Picking::RegisteredBoundId boundId, - const Picking::BoundRequestShapeBase& boundShapeData) + const ManipulatorId manipulatorId, const Picking::RegisteredBoundId boundId, const Picking::BoundRequestShapeBase& boundShapeData) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -99,8 +99,7 @@ namespace AzToolsFramework AZ_Assert(boundItr->second == manipulatorId, "Manipulator and its bounds are out of synchronization!"); } - const Picking::RegisteredBoundId newBoundId = - m_boundManager.UpdateOrRegisterBound(boundShapeData, boundId); + const Picking::RegisteredBoundId newBoundId = m_boundManager.UpdateOrRegisterBound(boundShapeData, boundId); if (newBoundId != boundId) { @@ -142,13 +141,6 @@ namespace AzToolsFramework } } - void ManipulatorManager::CheckModifierKeysChanged( - [[maybe_unused]] const ViewportInteraction::KeyboardModifiers keyboardModifiers, - const ViewportInteraction::MousePick& mousePick) - { - RefreshMouseOverState(mousePick); - } - void ManipulatorManager::DrawManipulators( AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, @@ -181,7 +173,8 @@ namespace AzToolsFramework if (found != m_boundIdToManipulatorIdMap.end()) { const auto manipulatorFound = m_manipulatorIdToPtrMap.find(found->second); - AZ_Assert(manipulatorFound != m_manipulatorIdToPtrMap.end(), + AZ_Assert( + manipulatorFound != m_manipulatorIdToPtrMap.end(), "Found a bound without a corresponding Manipulator, " "it's likely a bound was not cleaned up correctly"); rayIntersectionDistance = hitItr.second; @@ -194,10 +187,9 @@ namespace AzToolsFramework bool ManipulatorManager::ConsumeViewportMousePress(const ViewportInteraction::MouseInteraction& interaction) { - if (auto pickedManipulator = PickManipulator(interaction.m_mousePick); - pickedManipulator.has_value()) + if (auto pickedManipulator = PickManipulator(interaction.m_mousePick); pickedManipulator.has_value()) { - auto[manipulator, intersectionDistance] = pickedManipulator.value(); + auto [manipulator, intersectionDistance] = pickedManipulator.value(); if (interaction.m_mouseButtons.Left()) { @@ -249,24 +241,19 @@ namespace AzToolsFramework const ViewportInteraction::MousePick& mousePick) { float intersectionDistance = 0.0f; - const AZStd::shared_ptr pickedManipulator = PerformRaycast( - mousePick.m_rayOrigin, mousePick.m_rayDirection, intersectionDistance); + const AZStd::shared_ptr pickedManipulator = + PerformRaycast(mousePick.m_rayOrigin, mousePick.m_rayDirection, intersectionDistance); - return pickedManipulator.get() != nullptr - ? AZStd::make_optional(AZStd::make_tuple(pickedManipulator, intersectionDistance)) - : AZStd::nullopt; + return pickedManipulator.get() != nullptr ? AZStd::make_optional(AZStd::make_tuple(pickedManipulator, intersectionDistance)) + : AZStd::nullopt; } - ManipulatorManager::PickedManipulatorId ManipulatorManager::PickManipulatorId( - const ViewportInteraction::MousePick& mousePick) + ManipulatorManager::PickedManipulatorId ManipulatorManager::PickManipulatorId(const ViewportInteraction::MousePick& mousePick) { - auto [manipulator, intersectionDistance] = - PickManipulator(mousePick).value_or(PickedManipulator(nullptr, 0.0f)); - const ManipulatorId pickedManipulatorId = manipulator - ? manipulator->GetManipulatorId() - : InvalidManipulatorId; + auto [manipulator, intersectionDistance] = PickManipulator(mousePick).value_or(PickedManipulator(nullptr, 0.0f)); + const ManipulatorId pickedManipulatorId = manipulator ? manipulator->GetManipulatorId() : InvalidManipulatorId; - return PickedManipulatorId{pickedManipulatorId, intersectionDistance}; + return PickedManipulatorId{ pickedManipulatorId, intersectionDistance }; } ManipulatorManager::ConsumeMouseMoveResult ManipulatorManager::ConsumeViewportMouseMove( diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorManager.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorManager.h index 5f57738b8c..66b38579ef 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorManager.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorManager.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -23,7 +23,7 @@ namespace AzFramework { struct CameraState; class DebugDisplayRequests; -} +} // namespace AzFramework namespace AzToolsFramework { @@ -40,15 +40,15 @@ namespace AzToolsFramework class BaseManipulator; class LinearManipulator; - /// State of overall manipulator manager. + //! State of overall manipulator manager. struct ManipulatorManagerState { bool m_interacting; }; - /// This class serves to manage all relevant mouse events and coordinate all registered manipulators to function properly. - /// ManipulatorManager does not manage the life cycle of specific manipulators. The users of manipulators are responsible - /// for creating and deleting them at right time, as well as registering and unregistering accordingly. + //! This class serves to manage all relevant mouse events and coordinate all registered manipulators to function properly. + //! ManipulatorManager does not manage the life cycle of specific manipulators. The users of manipulators are responsible + //! for creating and deleting them at right time, as well as registering and unregistering accordingly. class ManipulatorManager : private ManipulatorManagerRequestBus::Handler , private EditorEntityInfoNotificationBus::Handler @@ -59,7 +59,7 @@ namespace AzToolsFramework explicit ManipulatorManager(ManipulatorManagerId managerId); ~ManipulatorManager(); - /// The result of consuming a mouse move. + //! The result of consuming a mouse move. enum class ConsumeMouseMoveResult { None, @@ -80,57 +80,52 @@ namespace AzToolsFramework void DeleteManipulatorBound(Picking::RegisteredBoundId boundId) override; void SetBoundDirty(Picking::RegisteredBoundId boundId) override; Picking::RegisteredBoundId UpdateBound( - ManipulatorId manipulatorId, Picking::RegisteredBoundId boundId, - const Picking::BoundRequestShapeBase& boundShapeData) override; - bool Interacting() const override { return m_activeManipulator != nullptr; } + ManipulatorId manipulatorId, Picking::RegisteredBoundId boundId, const Picking::BoundRequestShapeBase& boundShapeData) override; + bool Interacting() const override + { + return m_activeManipulator != nullptr; + } void DrawManipulators( AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction); - // O3DE_DEPRECATED(LY-117150) - /// Check if the modifier key state has changed - if so we may need to refresh - /// certain manipulator bounds. - AZ_DEPRECATED( - void CheckModifierKeysChanged( - ViewportInteraction::KeyboardModifiers keyboardModifiers, - const ViewportInteraction::MousePick& mousePick), - "CheckModifierKeysChanged is deprecated and will be removed in a future release"); - protected: - /// @param rayOrigin The origin of the ray to test intersection with. - /// @param rayDirection The direction of the ray to test intersection with. - /// @param[out] rayIntersectionDistance The result intersecting point equals "rayOrigin + rayIntersectionDistance * rayDirection". - /// @return A pointer to a manipulator that the ray intersects. Null pointer if no intersection is detected. + //! @param rayOrigin The origin of the ray to test intersection with. + //! @param rayDirection The direction of the ray to test intersection with. + //! @param[out] rayIntersectionDistance The result intersecting point equals "rayOrigin + rayIntersectionDistance * rayDirection". + //! @return A pointer to a manipulator that the ray intersects. Null pointer if no intersection is detected. AZStd::shared_ptr PerformRaycast( const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, float& rayIntersectionDistance); // EditorEntityInfoNotifications ... void OnEntityInfoUpdatedVisibility(AZ::EntityId entityId, bool visible) override; - /// Alias for a Manipulator and intersection distance. + //! Alias for a Manipulator and intersection distance. using PickedManipulator = AZStd::tuple, float>; - /// Alias for a ManipulatorId and intersection distance. + //! Alias for a ManipulatorId and intersection distance. using PickedManipulatorId = AZStd::tuple; - /// Return the picked manipulator and intersection distance if a manipulator was intersected. + //! Return the picked manipulator and intersection distance if a manipulator was intersected. AZStd::optional PickManipulator(const ViewportInteraction::MousePick& mousePick); - /// Wrapper for PickManipulator to return the ManipulatorId directly. + //! Wrapper for PickManipulator to return the ManipulatorId directly. PickedManipulatorId PickManipulatorId(const ViewportInteraction::MousePick& mousePick); - /// Called once per frame after all manipulators have been drawn (and their - /// bounds updated if required). + //! Called once per frame after all manipulators have been drawn (and their + //! bounds updated if required). void RefreshMouseOverState(const ViewportInteraction::MousePick& mousePick); - ManipulatorManagerId m_manipulatorManagerId; ///< This manipulator manager's id. - ManipulatorId m_nextManipulatorIdToGenerate; ///< Id to use for the next manipulator that is registered with this manager. + ManipulatorManagerId m_manipulatorManagerId; //!< This manipulator manager's id. + ManipulatorId m_nextManipulatorIdToGenerate; //!< Id to use for the next manipulator that is registered with this manager. - AZStd::unordered_map> m_manipulatorIdToPtrMap; ///< Mapping from a manipulatorId to the corresponding manipulator. - AZStd::unordered_map m_boundIdToManipulatorIdMap; ///< Mapping from a boundId to the corresponding manipulatorId. + AZStd::unordered_map> + m_manipulatorIdToPtrMap; //!< Mapping from a manipulatorId to the corresponding manipulator. + AZStd::unordered_map + m_boundIdToManipulatorIdMap; //!< Mapping from a boundId to the corresponding manipulatorId. - AZStd::shared_ptr m_activeManipulator; ///< The manipulator we are currently interacting with. - Picking::ManipulatorBoundManager m_boundManager; ///< All active manipulator bounds that could be interacted with. + AZStd::shared_ptr m_activeManipulator; //!< The manipulator we are currently interacting with. + Picking::ManipulatorBoundManager m_boundManager; //!< All active manipulator bounds that could be interacted with. }; // The main/default ManipulatorManagerId to be used for diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp index 8a6398d025..427bb9e9d1 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "ManipulatorSnapping.h" @@ -19,19 +19,27 @@ #include AZ_CVAR( - AZ::Color, cl_viewportGridMainColor, AZ::Color::CreateFromRgba(26, 26, 26, 127), nullptr, - AZ::ConsoleFunctorFlags::Null, "Main color for snapping grid"); + AZ::Color, + cl_viewportGridMainColor, + AZ::Color::CreateFromRgba(26, 26, 26, 127), + nullptr, + AZ::ConsoleFunctorFlags::Null, + "Main color for snapping grid"); AZ_CVAR( - AZ::Color, cl_viewportGridFadeColor, AZ::Color::CreateFromRgba(127, 127, 127, 0), nullptr, - AZ::ConsoleFunctorFlags::Null, "Fade color for snapping grid"); + AZ::Color, + cl_viewportGridFadeColor, + AZ::Color::CreateFromRgba(127, 127, 127, 0), + nullptr, + AZ::ConsoleFunctorFlags::Null, + "Fade color for snapping grid"); +AZ_CVAR(int, cl_viewportGridSquareCount, 20, nullptr, AZ::ConsoleFunctorFlags::Null, "Number of grid squares for snapping grid"); +AZ_CVAR(float, cl_viewportGridLineWidth, 1.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "Width of grid lines for snapping grid"); AZ_CVAR( - int, cl_viewportGridSquareCount, 20, nullptr, AZ::ConsoleFunctorFlags::Null, - "Number of grid squares for snapping grid"); -AZ_CVAR( - float, cl_viewportGridLineWidth, 1.0f, nullptr, AZ::ConsoleFunctorFlags::Null, - "Width of grid lines for snapping grid"); -AZ_CVAR( - float, cl_viewportFadeLineDistanceScale, 1.0f, nullptr, AZ::ConsoleFunctorFlags::Null, + float, + cl_viewportFadeLineDistanceScale, + 1.0f, + nullptr, + AZ::ConsoleFunctorFlags::Null, "The scale to be applied to the line that fades out (scales the current gridSize)"); namespace AzToolsFramework @@ -43,16 +51,17 @@ namespace AzToolsFramework } ManipulatorInteraction BuildManipulatorInteraction( - const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, - const AZ::Vector3& worldRayOrigin, const AZ::Vector3& worldRayDirection) + const AZ::Transform& worldFromLocal, + const AZ::Vector3& nonUniformScale, + const AZ::Vector3& worldRayOrigin, + const AZ::Vector3& worldRayDirection) { const AZ::Transform worldFromLocalUniform = AzToolsFramework::TransformUniformScale(worldFromLocal); const AZ::Transform localFromWorldUniform = worldFromLocalUniform.GetInverse(); - return {localFromWorldUniform.TransformPoint(worldRayOrigin), - TransformDirectionNoScaling(localFromWorldUniform, worldRayDirection), - NonUniformScaleReciprocal(nonUniformScale), - ScaleReciprocal(worldFromLocalUniform)}; + return { localFromWorldUniform.TransformPoint(worldRayOrigin), + TransformDirectionNoScaling(localFromWorldUniform, worldRayDirection), NonUniformScaleReciprocal(nonUniformScale), + ScaleReciprocal(worldFromLocalUniform) }; } struct SnapAdjustment @@ -87,8 +96,7 @@ namespace AzToolsFramework } AZ::Vector3 CalculateSnappedTerrainPosition( - const AZ::Vector3& worldSurfacePosition, const AZ::Transform& worldFromLocal, - const int viewportId, const float gridSize) + const AZ::Vector3& worldSurfacePosition, const AZ::Transform& worldFromLocal, const int viewportId, const float gridSize) { const AZ::Transform localFromWorld = worldFromLocal.GetInverse(); const AZ::Vector3 localSurfacePosition = localFromWorld.TransformPoint(worldSurfacePosition); @@ -101,8 +109,7 @@ namespace AzToolsFramework // find terrain height at xy snapped location float terrainHeight = 0.0f; ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult( - terrainHeight, viewportId, - &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::TerrainHeight, + terrainHeight, viewportId, &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::TerrainHeight, Vector3ToVector2(worldFromLocal.TransformPoint(localSnappedSurfacePosition))); // set snapped z value to terrain height @@ -116,8 +123,7 @@ namespace AzToolsFramework { bool snapping = false; ViewportInteraction::ViewportInteractionRequestBus::EventResult( - snapping, viewportId, - &ViewportInteraction::ViewportInteractionRequestBus::Events::GridSnappingEnabled); + snapping, viewportId, &ViewportInteraction::ViewportInteractionRequestBus::Events::GridSnappingEnabled); return snapping; } @@ -126,8 +132,7 @@ namespace AzToolsFramework { float gridSize = 0.0f; ViewportInteraction::ViewportInteractionRequestBus::EventResult( - gridSize, viewportId, - &ViewportInteraction::ViewportInteractionRequestBus::Events::GridSize); + gridSize, viewportId, &ViewportInteraction::ViewportInteractionRequestBus::Events::GridSize); return gridSize; } @@ -136,7 +141,8 @@ namespace AzToolsFramework { bool snapping = GridSnapping(viewportId); const float gridSize = GridSize(viewportId); - if (AZ::IsClose(gridSize, 0.0f, 1e-2f)) // Same threshold value as min value for m_spinBox in SnapToWidget constructor in MainWindow.cpp + if (AZ::IsClose( + gridSize, 0.0f, 1e-2f)) // Same threshold value as min value for m_spinBox in SnapToWidget constructor in MainWindow.cpp { snapping = false; } @@ -148,8 +154,7 @@ namespace AzToolsFramework { bool snapping = false; ViewportInteraction::ViewportInteractionRequestBus::EventResult( - snapping, viewportId, - &ViewportInteraction::ViewportInteractionRequestBus::Events::AngleSnappingEnabled); + snapping, viewportId, &ViewportInteraction::ViewportInteractionRequestBus::Events::AngleSnappingEnabled); return snapping; } @@ -158,8 +163,7 @@ namespace AzToolsFramework { float angle = 0.0f; ViewportInteraction::ViewportInteractionRequestBus::EventResult( - angle, viewportId, - &ViewportInteraction::ViewportInteractionRequestBus::Events::AngleStep); + angle, viewportId, &ViewportInteraction::ViewportInteractionRequestBus::Events::AngleStep); return angle; } @@ -168,14 +172,12 @@ namespace AzToolsFramework { bool show = false; ViewportInteraction::ViewportInteractionRequestBus::EventResult( - show, viewportId, - &ViewportInteraction::ViewportInteractionRequestBus::Events::ShowGrid); + show, viewportId, &ViewportInteraction::ViewportInteractionRequestBus::Events::ShowGrid); return show; } - void DrawSnappingGrid( - AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Transform& worldFromLocal, const float squareSize) + void DrawSnappingGrid(AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Transform& worldFromLocal, const float squareSize) { debugDisplay.PushMatrix(worldFromLocal); @@ -197,21 +199,17 @@ namespace AzToolsFramework // draw the faded end parts of the grid lines debugDisplay.DrawLine( - AZ::Vector3(lineOffset, -halfGridSize, 0.0f), - AZ::Vector3(lineOffset, -(halfGridSize + fadeLineLength), 0.0f), + AZ::Vector3(lineOffset, -halfGridSize, 0.0f), AZ::Vector3(lineOffset, -(halfGridSize + fadeLineLength), 0.0f), gridMainColor, gridFadeColor); debugDisplay.DrawLine( - AZ::Vector3(lineOffset, halfGridSize, 0.0f), - AZ::Vector3(lineOffset, (halfGridSize + fadeLineLength), 0.0f), - gridMainColor, gridFadeColor); + AZ::Vector3(lineOffset, halfGridSize, 0.0f), AZ::Vector3(lineOffset, (halfGridSize + fadeLineLength), 0.0f), gridMainColor, + gridFadeColor); debugDisplay.DrawLine( - AZ::Vector3(-halfGridSize, lineOffset, 0.0f), - AZ::Vector3(-(halfGridSize + fadeLineLength), lineOffset, 0.0f), + AZ::Vector3(-halfGridSize, lineOffset, 0.0f), AZ::Vector3(-(halfGridSize + fadeLineLength), lineOffset, 0.0f), gridMainColor, gridFadeColor); debugDisplay.DrawLine( - AZ::Vector3(halfGridSize, lineOffset, 0.0f), - AZ::Vector3((halfGridSize + fadeLineLength), lineOffset, 0.0f), - gridMainColor, gridFadeColor); + AZ::Vector3(halfGridSize, lineOffset, 0.0f), AZ::Vector3((halfGridSize + fadeLineLength), lineOffset, 0.0f), gridMainColor, + gridFadeColor); // build a vector of the main grid lines to draw (start and end positions) lines.push_back(AZ::Vector3(lineOffset, -halfGridSize, 0.0f)); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.h index 11860780c7..f2fa104d4c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.h @@ -1,19 +1,19 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once -#include #include +#include namespace AzFramework { @@ -22,7 +22,7 @@ namespace AzFramework namespace AzToolsFramework { - /// Structure to encapsulate grid snapping properties. + //! Structure to encapsulate grid snapping properties. struct GridSnapParameters { GridSnapParameters(bool gridSnap, float gridSize); @@ -31,96 +31,92 @@ namespace AzToolsFramework float m_gridSize; }; - /// Structure to hold transformed incoming viewport interaction from world space to manipulator space. + //! Structure to hold transformed incoming viewport interaction from world space to manipulator space. struct ManipulatorInteraction { - AZ::Vector3 m_localRayOrigin; ///< The ray origin (start) in the reference from of the manipulator. - AZ::Vector3 m_localRayDirection; ///< The ray direction in the reference from of the manipulator. - AZ::Vector3 m_nonUniformScaleReciprocal; ///< Handles inverting any non-uniform scale which was applied - ///< separately from the transform. - float m_scaleReciprocal; ///< The scale reciprocal (1.0 / scale) of the transform used to move the - ///< ray from world space to local space. + AZ::Vector3 m_localRayOrigin; //!< The ray origin (start) in the reference from of the manipulator. + AZ::Vector3 m_localRayDirection; //!< The ray direction in the reference from of the manipulator. + AZ::Vector3 m_nonUniformScaleReciprocal; //!< Handles inverting any non-uniform scale which was applied + //!< separately from the transform. + float m_scaleReciprocal; //!< The scale reciprocal (1.0 / scale) of the transform used to move the + //!< ray from world space to local space. }; - /// Build a ManipulatorInteraction structure from the incoming viewport interaction. + //! Build a ManipulatorInteraction structure from the incoming viewport interaction. ManipulatorInteraction BuildManipulatorInteraction( - const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, - const AZ::Vector3& worldRayOrigin, const AZ::Vector3& worldRayDirection); - - /// Calculate the offset along an axis to adjust a position to stay snapped to a given grid size. - /// @note This is snap up or down to the nearest grid segment (e.g. 0.2 snaps to 0.0 -> delta 0.2, - /// 0.7 snaps to 1.0 -> delta 0.3). - AZ::Vector3 CalculateSnappedOffset( - const AZ::Vector3& unsnappedPosition, const AZ::Vector3& axis, float size); - - /// Return the amount to snap from the starting position given the current grid size. - /// @note A movement of more than half size (in either direction) will cause a snap by size. + const AZ::Transform& worldFromLocal, + const AZ::Vector3& nonUniformScale, + const AZ::Vector3& worldRayOrigin, + const AZ::Vector3& worldRayDirection); + + //! Calculate the offset along an axis to adjust a position to stay snapped to a given grid size. + //! @note This is snap up or down to the nearest grid segment (e.g. 0.2 snaps to 0.0 -> delta 0.2, + //! 0.7 snaps to 1.0 -> delta 0.3). + AZ::Vector3 CalculateSnappedOffset(const AZ::Vector3& unsnappedPosition, const AZ::Vector3& axis, float size); + + //! Return the amount to snap from the starting position given the current grid size. + //! @note A movement of more than half size (in either direction) will cause a snap by size. AZ::Vector3 CalculateSnappedAmount(const AZ::Vector3& unsnappedPosition, const AZ::Vector3& axis, float size); - /// For a given point on the terrain, calculate the closest xy position snapped to the grid - /// (z position is aligned to terrain height, not snapped to z grid) + //! For a given point on the terrain, calculate the closest xy position snapped to the grid + //! (z position is aligned to terrain height, not snapped to z grid) AZ::Vector3 CalculateSnappedTerrainPosition( - const AZ::Vector3& worldSurfacePosition, const AZ::Transform& worldFromLocal, - int viewportId, float gridSize); + const AZ::Vector3& worldSurfacePosition, const AZ::Transform& worldFromLocal, int viewportId, float gridSize); - /// Wrapper for grid snapping and grid size bus calls. + //! Wrapper for grid snapping and grid size bus calls. GridSnapParameters GridSnapSettings(int viewportId); - /// Wrapper for angle snapping enabled bus call. + //! Wrapper for angle snapping enabled bus call. bool AngleSnapping(int viewportId); - /// Wrapper for angle snapping increment bus call. - /// @return Angle in degrees + //! Wrapper for angle snapping increment bus call. + //! @return Angle in degrees. float AngleStep(int viewportId); - /// Wrapper for grid rendering check call. + //! Wrapper for grid rendering check call. bool ShowingGrid(int viewportId); - /// Render the grid used for snapping. - void DrawSnappingGrid( - AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Transform& worldFromLocal, float squareSize); + //! Render the grid used for snapping. + void DrawSnappingGrid(AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Transform& worldFromLocal, float squareSize); - /// Round to x number of significant digits. - /// @param value Number to round. - /// @param exponent Precision to use when rounding. + //! Round to x number of significant digits. + //! @param value Number to round. + //! @param exponent Precision to use when rounding. inline float Round(const float value, const float exponent) { const float precision = std::pow(10.0f, exponent); return roundf(value * precision) / precision; } - /// Round to 3 significant digits (3 digits common usage). + //! Round to 3 significant digits (3 digits common usage). inline float Round3(const float value) { return Round(value, 3.0f); } - /// Util to return sign of floating point number. - /// value > 0 return 1.0 - /// value < 0 return -1.0 - /// value == 0 return 0.0 + //! Util to return sign of floating point number. + //! value > 0 return 1.0 + //! value < 0 return -1.0 + //! value == 0 return 0.0 inline float Sign(const float value) { return static_cast((0.0f < value) - (value < 0.0f)); } - /// Find the max scale element and return the reciprocal of it. - /// Note: The reciprocal will be rounded to three significant digits to eliminate - /// noise in the value returned when dealing with values far from the origin. + //! Find the max scale element and return the reciprocal of it. + //! Note: The reciprocal will be rounded to three significant digits to eliminate + //! noise in the value returned when dealing with values far from the origin. inline float ScaleReciprocal(const AZ::Transform& transform) { return Round3(1.0f / transform.GetUniformScale()); } - /// Find the reciprocal of the non-uniform scale. - /// Each element will be rounded to three significant digits to eliminate noise - /// when dealing with values far from the origin. + //! Find the reciprocal of the non-uniform scale. + //! Each element will be rounded to three significant digits to eliminate noise + //! when dealing with values far from the origin. inline AZ::Vector3 NonUniformScaleReciprocal(const AZ::Vector3& nonUniformScale) { AZ::Vector3 scaleReciprocal = nonUniformScale.GetReciprocal(); - return AZ::Vector3( - Round3(scaleReciprocal.GetX()), - Round3(scaleReciprocal.GetY()), - Round3(scaleReciprocal.GetZ())); + return AZ::Vector3(Round3(scaleReciprocal.GetX()), Round3(scaleReciprocal.GetY()), Round3(scaleReciprocal.GetZ())); } } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSpace.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSpace.h index e26c6b8947..7c1176dd2c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSpace.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSpace.h @@ -20,7 +20,7 @@ namespace AZ namespace AzToolsFramework { - /// Handles location for manipulators which have a global space but no local transformation. + //! Handles location for manipulators which have a global space but no local transformation. class ManipulatorSpace { public: @@ -32,17 +32,16 @@ namespace AzToolsFramework const AZ::Vector3& GetNonUniformScale() const; void SetNonUniformScale(const AZ::Vector3& nonUniformScale); - /// Calculates a transform combining the space and local transform, taking non-uniform scale into account. + //! Calculates a transform combining the space and local transform, taking non-uniform scale into account. AZ::Transform ApplySpace(const AZ::Transform& localTransform) const; private: - AZ::Transform m_space = AZ::Transform::CreateIdentity(); ///< Space the manipulator is in. - AZ::Vector3 m_nonUniformScale = AZ::Vector3::CreateOne(); ///< Handles non-uniform scale for the space the manipulator is in. + AZ::Transform m_space = AZ::Transform::CreateIdentity(); //!< Space the manipulator is in. + AZ::Vector3 m_nonUniformScale = AZ::Vector3::CreateOne(); //!< Handles non-uniform scale for the space the manipulator is in. }; - /// Handles location for manipulators which have a global space and a local position, but no local rotation. - class ManipulatorSpaceWithLocalPosition - : public ManipulatorSpace + //! Handles location for manipulators which have a global space and a local position, but no local rotation. + class ManipulatorSpaceWithLocalPosition : public ManipulatorSpace { public: AZ_TYPE_INFO(ManipulatorSpaceWithLocalPosition, "{47BE15AF-60A8-436B-8F3F-7DDFB97220E6}") @@ -52,12 +51,11 @@ namespace AzToolsFramework void SetLocalPosition(const AZ::Vector3& localPosition); private: - AZ::Vector3 m_localPosition = AZ::Vector3::CreateZero(); ///< Position in local space. + AZ::Vector3 m_localPosition = AZ::Vector3::CreateZero(); //!< Position in local space. }; - /// Handles location for manipulators which have a global space and a local transform (position and rotation). - class ManipulatorSpaceWithLocalTransform - : public ManipulatorSpace + //! Handles location for manipulators which have a global space and a local transform (position and rotation). + class ManipulatorSpaceWithLocalTransform : public ManipulatorSpace { public: AZ_TYPE_INFO(ManipulatorSpaceWithLocalTransform, "{6D100797-1DD8-45B0-A21C-8893B770C0BC}") @@ -72,6 +70,6 @@ namespace AzToolsFramework void SetLocalOrientation(const AZ::Quaternion& localOrientation); private: - AZ::Transform m_localTransform = AZ::Transform::CreateIdentity(); ///< Local transform. + AZ::Transform m_localTransform = AZ::Transform::CreateIdentity(); //!< Local transform. }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.cpp index 150e23041d..a4c4a59ee6 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.cpp @@ -1,26 +1,26 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "ManipulatorView.h" -#include #include +#include #include #include #include -#include #include -#include #include +#include +#include #include #include #include @@ -33,8 +33,7 @@ namespace AzToolsFramework AZ::Transform WorldFromLocalWithUniformScale(const AZ::EntityId entityId) { AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity(); - AZ::TransformBus::EventResult( - worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM); + AZ::TransformBus::EventResult(worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM); return TransformUniformScale(worldFromLocal); } @@ -56,13 +55,16 @@ namespace AzToolsFramework return AzToolsFramework::TransformDirectionNoScaling(m_worldFromLocal, direction); } - /// Take into account the location of the camera and orientate the axis so it faces the camera. - /// if we did correct the camera (shouldCorrect is true) then we know the axis facing us it negative. - /// we can use this to change the rendering for a flipped axis if we wish. + // Take into account the location of the camera and orientate the axis so it faces the camera. + // if we did correct the camera (shouldCorrect is true) then we know the axis facing us it negative. + // we can use this to change the rendering for a flipped axis if we wish. static void CameraCorrectAxis( - const AZ::Vector3& axis, AZ::Vector3& correctedAxis, const ManipulatorManagerState& managerState, + const AZ::Vector3& axis, + AZ::Vector3& correctedAxis, + const ManipulatorManagerState& managerState, const ViewportInteraction::MouseInteraction& mouseInteraction, - const AZ::Transform& worldFromLocal, const AZ::Vector3& localPosition, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& localPosition, const AzFramework::CameraState& cameraState, bool* shouldCorrect = nullptr) { @@ -74,9 +76,7 @@ namespace AzToolsFramework const bool correcting = ShouldFlipCameraAxis(worldFromLocal, localPosition, axis, cameraState); // the corrected axis, if no flip was required, output == input - correctedAxis = correcting - ? -axis - : axis; + correctedAxis = correcting ? -axis : axis; // optional out ref to use if we care about the result if (shouldCorrect) @@ -86,10 +86,13 @@ namespace AzToolsFramework } } - /// Calculate quad bound in world space. + // calculate quad bound in world space. static Picking::BoundShapeQuad CalculateQuadBound( - const AZ::Vector3& localPosition, const ManipulatorState& manipulatorState, - const AZ::Vector3& axis1, const AZ::Vector3& axis2, const float size) + const AZ::Vector3& localPosition, + const ManipulatorState& manipulatorState, + const AZ::Vector3& axis1, + const AZ::Vector3& axis2, + const float size) { const AZ::Vector3 worldPosition = manipulatorState.TransformPoint(localPosition); const AZ::Vector3 endAxis1World = manipulatorState.TransformDirectionNoScaling(axis1) * size; @@ -104,8 +107,10 @@ namespace AzToolsFramework } static Picking::BoundShapeQuad CalculateQuadBoundBillboard( - const AZ::Vector3& localPosition, const AZ::Transform& worldFromLocal, - const float size, const AzFramework::CameraState& cameraState) + const AZ::Vector3& localPosition, + const AZ::Transform& worldFromLocal, + const float size, + const AzFramework::CameraState& cameraState) { const AZ::Vector3 worldPosition = worldFromLocal.TransformPoint(localPosition); @@ -117,10 +122,13 @@ namespace AzToolsFramework return quadBound; } - /// Calculate line bound in world space (axis and length). + // calculate line bound in world space (axis and length). static Picking::BoundShapeLineSegment CalculateLineBound( - const AZ::Vector3& localPosition, const AZ::Transform& worldFromLocal, - const AZ::Vector3& axis, const float length, const float width) + const AZ::Vector3& localPosition, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& axis, + const float length, + const float width) { Picking::BoundShapeLineSegment lineBound; lineBound.m_start = worldFromLocal.TransformPoint(localPosition); @@ -129,7 +137,7 @@ namespace AzToolsFramework return lineBound; } - /// Calculate line bound in world space (start and end point). + // calculate line bound in world space (start and end point). static Picking::BoundShapeLineSegment CalculateLineBound( const AZ::Vector3& localStartPosition, const AZ::Vector3& localEndPosition, @@ -143,10 +151,14 @@ namespace AzToolsFramework return lineBound; } - /// Calculate cone bound in world space. + // calculate cone bound in world space. static Picking::BoundShapeCone CalculateConeBound( - const AZ::Vector3& localPosition, const AZ::Transform& worldFromLocal, - const AZ::Vector3& axis, const AZ::Vector3& offset, const float length, const float radius) + const AZ::Vector3& localPosition, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& axis, + const AZ::Vector3& offset, + const float length, + const float radius) { Picking::BoundShapeCone coneBound; coneBound.m_radius = radius; @@ -156,10 +168,13 @@ namespace AzToolsFramework return coneBound; } - /// Calculate box bound in world space. + // calculate box bound in world space. static Picking::BoundShapeBox CalculateBoxBound( - const AZ::Vector3& localPosition, const AZ::Transform& worldFromLocal, - const AZ::Quaternion& orientation, const AZ::Vector3& offset, const AZ::Vector3& halfExtents) + const AZ::Vector3& localPosition, + const AZ::Transform& worldFromLocal, + const AZ::Quaternion& orientation, + const AZ::Vector3& offset, + const AZ::Vector3& halfExtents) { Picking::BoundShapeBox boxBound; boxBound.m_halfExtents = halfExtents; @@ -168,10 +183,13 @@ namespace AzToolsFramework return boxBound; } - /// Calculate cylinder bound in world space. + // calculate cylinder bound in world space. static Picking::BoundShapeCylinder CalculateCylinderBound( - const AZ::Vector3& localPosition, const AZ::Transform& worldFromLocal, - const AZ::Vector3& axis, const float length, const float radius) + const AZ::Vector3& localPosition, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& axis, + const float length, + const float radius) { Picking::BoundShapeCylinder boxBound; boxBound.m_base = worldFromLocal.TransformPoint(localPosition); @@ -181,10 +199,9 @@ namespace AzToolsFramework return boxBound; } - /// Calculate sphere bound in world space. + // calculate sphere bound in world space. static Picking::BoundShapeSphere CalculateSphereBound( - const AZ::Vector3& localPosition, const ManipulatorState& manipulatorState, - const float radius) + const AZ::Vector3& localPosition, const ManipulatorState& manipulatorState, const float radius) { Picking::BoundShapeSphere sphereBound; sphereBound.m_center = manipulatorState.TransformPoint(localPosition); @@ -192,10 +209,13 @@ namespace AzToolsFramework return sphereBound; } - /// Calculate torus bound in world space. + // calculate torus bound in world space. static Picking::BoundShapeTorus CalculateTorusBound( - const AZ::Vector3& localPosition, const AZ::Transform& worldFromLocal, - const AZ::Vector3& axis, const float radius, const float width) + const AZ::Vector3& localPosition, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& axis, + const float radius, + const float width) { Picking::BoundShapeTorus torusBound; torusBound.m_center = worldFromLocal.TransformPoint(localPosition); @@ -205,7 +225,7 @@ namespace AzToolsFramework return torusBound; } - /// Calculate spline bound in world space. + // calculate spline bound in world space. static Picking::BoundShapeSpline CalculateSplineBound( const AZStd::weak_ptr& spline, const AZ::Transform& worldFromLocal, const float width) { @@ -224,8 +244,7 @@ namespace AzToolsFramework return lineWidth[mouseOver]; } - static AZ::Color ViewColor( - const bool mouseOver, const AZ::Color& defaultColor, const AZ::Color& mouseOverColor) + static AZ::Color ViewColor(const bool mouseOver, const AZ::Color& defaultColor, const AZ::Color& mouseOverColor) { const AZStd::array viewColor = { { defaultColor, mouseOverColor } }; return viewColor[mouseOver].GetAsVector4(); @@ -250,19 +269,16 @@ namespace AzToolsFramework void ManipulatorView::SetBoundDirty(const ManipulatorManagerId managerId) { - ManipulatorManagerRequestBus::Event( - managerId, &ManipulatorManagerRequestBus::Events::SetBoundDirty, m_boundId); + ManipulatorManagerRequestBus::Event(managerId, &ManipulatorManagerRequestBus::Events::SetBoundDirty, m_boundId); m_boundDirty = true; } void ManipulatorView::RefreshBound( - const ManipulatorManagerId managerId, const ManipulatorId manipulatorId, - const Picking::BoundRequestShapeBase& bound) + const ManipulatorManagerId managerId, const ManipulatorId manipulatorId, const Picking::BoundRequestShapeBase& bound) { ManipulatorManagerRequestBus::EventResult( - m_boundId, managerId, &ManipulatorManagerRequestBus::Events::UpdateBound, - manipulatorId, m_boundId, bound); + m_boundId, managerId, &ManipulatorManagerRequestBus::Events::UpdateBound, manipulatorId, m_boundId, bound); // store the manager id if we know the bound has been registered m_managerId = managerId; @@ -271,8 +287,7 @@ namespace AzToolsFramework } void ManipulatorView::RefreshBoundInternal( - const ManipulatorManagerId managerId, const ManipulatorId manipulatorId, - const Picking::BoundRequestShapeBase& bound) + const ManipulatorManagerId managerId, const ManipulatorId manipulatorId, const Picking::BoundRequestShapeBase& bound) { // update the manipulator's bounds if necessary // if m_screenSizeFixed is true, any camera movement can potentially change the size @@ -287,8 +302,7 @@ namespace AzToolsFramework { if (m_boundId != Picking::InvalidBoundId) { - ManipulatorManagerRequestBus::Event( - managerId, &ManipulatorManagerRequestBus::Events::DeleteManipulatorBound, m_boundId); + ManipulatorManagerRequestBus::Event(managerId, &ManipulatorManagerRequestBus::Events::DeleteManipulatorBound, m_boundId); m_boundId = Picking::InvalidBoundId; } @@ -297,33 +311,34 @@ namespace AzToolsFramework float ManipulatorView::ManipulatorViewScaleMultiplier( const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState) const { - return ScreenSizeFixed() - ? CalculateScreenToWorldMultiplier(worldPosition, cameraState) - : 1.0f; + return ScreenSizeFixed() ? CalculateScreenToWorldMultiplier(worldPosition, cameraState) : 1.0f; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void ManipulatorViewQuad::Draw( - const ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + const ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + const ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) { const AZ::Vector3 axis1 = m_axis1; const AZ::Vector3 axis2 = m_axis2; CameraCorrectAxis( - axis1, m_cameraCorrectedAxis1, managerState, mouseInteraction, - manipulatorState.m_worldFromLocal, manipulatorState.m_localPosition, cameraState); + axis1, m_cameraCorrectedAxis1, managerState, mouseInteraction, manipulatorState.m_worldFromLocal, + manipulatorState.m_localPosition, cameraState); CameraCorrectAxis( - axis2, m_cameraCorrectedAxis2, managerState, mouseInteraction, - manipulatorState.m_worldFromLocal, manipulatorState.m_localPosition, cameraState); + axis2, m_cameraCorrectedAxis2, managerState, mouseInteraction, manipulatorState.m_worldFromLocal, + manipulatorState.m_localPosition, cameraState); - const Picking::BoundShapeQuad quadBound = - CalculateQuadBound( - manipulatorState.m_localPosition, manipulatorState, m_cameraCorrectedAxis1, m_cameraCorrectedAxis2, - m_size * ManipulatorViewScaleMultiplier( + const Picking::BoundShapeQuad quadBound = CalculateQuadBound( + manipulatorState.m_localPosition, manipulatorState, m_cameraCorrectedAxis1, m_cameraCorrectedAxis2, + m_size * + ManipulatorViewScaleMultiplier( manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState)); debugDisplay.SetLineWidth(defaultLineWidth(manipulatorState.m_mouseOver)); @@ -339,9 +354,7 @@ namespace AzToolsFramework debugDisplay.SetColor(Vector3ToVector4(m_mouseOverColor.GetAsVector3(), 0.5f)); debugDisplay.CullOff(); - debugDisplay.DrawQuad( - quadBound.m_corner1, quadBound.m_corner2, - quadBound.m_corner3, quadBound.m_corner4); + debugDisplay.DrawQuad(quadBound.m_corner1, quadBound.m_corner2, quadBound.m_corner3, quadBound.m_corner4); debugDisplay.CullOn(); } @@ -349,41 +362,46 @@ namespace AzToolsFramework } void ManipulatorViewQuadBillboard::Draw( - const ManipulatorManagerId managerId, const ManipulatorManagerState& /*managerState*/, - const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + const ManipulatorManagerId managerId, + const ManipulatorManagerState& /*managerState*/, + const ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& /*mouseInteraction*/) { - const Picking::BoundShapeQuad quadBound = - CalculateQuadBoundBillboard(manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, - m_size * ManipulatorViewScaleMultiplier( - manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState), cameraState); + const Picking::BoundShapeQuad quadBound = CalculateQuadBoundBillboard( + manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, + m_size * + ManipulatorViewScaleMultiplier( + manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState), + cameraState); debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_color, m_mouseOverColor).GetAsVector4()); - debugDisplay.DrawQuad( - quadBound.m_corner1, quadBound.m_corner2, - quadBound.m_corner3, quadBound.m_corner4); + debugDisplay.DrawQuad(quadBound.m_corner1, quadBound.m_corner2, quadBound.m_corner3, quadBound.m_corner4); RefreshBoundInternal(managerId, manipulatorId, quadBound); } void ManipulatorViewLine::Draw( - const ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + const ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + const ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) { - const float viewScale = ManipulatorViewScaleMultiplier( - manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState); + const float viewScale = + ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState); CameraCorrectAxis( - m_axis, m_cameraCorrectedAxis, managerState, mouseInteraction, - manipulatorState.m_worldFromLocal, manipulatorState.m_localPosition, cameraState); + m_axis, m_cameraCorrectedAxis, managerState, mouseInteraction, manipulatorState.m_worldFromLocal, + manipulatorState.m_localPosition, cameraState); - const Picking::BoundShapeLineSegment lineBound = - CalculateLineBound( - manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, - m_cameraCorrectedAxis, m_length * viewScale, m_width * viewScale); + const Picking::BoundShapeLineSegment lineBound = CalculateLineBound( + manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, m_cameraCorrectedAxis, m_length * viewScale, + m_width * viewScale); debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_color, m_mouseOverColor).GetAsVector4()); debugDisplay.SetLineWidth(defaultLineWidth(manipulatorState.m_mouseOver)); @@ -393,13 +411,16 @@ namespace AzToolsFramework } void ManipulatorViewLineSelect::Draw( - const ManipulatorManagerId managerId, const ManipulatorManagerState& /*managerState*/, - const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + const ManipulatorManagerId managerId, + const ManipulatorManagerState& /*managerState*/, + const ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) { - const float viewScale = ManipulatorViewScaleMultiplier( - manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState); + const float viewScale = + ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState); const Picking::BoundShapeLineSegment lineBound = CalculateLineBound(m_localStart, m_localEnd, manipulatorState, m_width * viewScale); @@ -407,44 +428,42 @@ namespace AzToolsFramework if (manipulatorState.m_mouseOver) { const LineSegmentSelectionManipulator::Action action = CalculateManipulationDataAction( - manipulatorState.m_worldFromLocal, manipulatorState.m_nonUniformScale, - mouseInteraction.m_mousePick.m_rayOrigin, mouseInteraction.m_mousePick.m_rayDirection, - cameraState.m_farClip, m_localStart, m_localEnd); + manipulatorState.m_worldFromLocal, manipulatorState.m_nonUniformScale, mouseInteraction.m_mousePick.m_rayOrigin, + mouseInteraction.m_mousePick.m_rayDirection, cameraState.m_farClip, m_localStart, m_localEnd); const AZ::Vector3 worldLineHitPosition = manipulatorState.TransformPoint(action.m_localLineHitPosition); debugDisplay.SetColor(AZ::Vector4(0.0f, 1.0f, 0.0f, 1.0f)); debugDisplay.DrawBall( - worldLineHitPosition, ManipulatorViewScaleMultiplier(worldLineHitPosition, cameraState) - * g_defaultManipulatorSphereRadius, false); + worldLineHitPosition, ManipulatorViewScaleMultiplier(worldLineHitPosition, cameraState) * g_defaultManipulatorSphereRadius, + false); } RefreshBoundInternal(managerId, manipulatorId, lineBound); } void ManipulatorViewCone::Draw( - const ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + const ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + const ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) { - const float viewScale = ManipulatorViewScaleMultiplier( - manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState); + const float viewScale = + ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState); CameraCorrectAxis( - m_axis, m_cameraCorrectedAxis, managerState, mouseInteraction, - manipulatorState.m_worldFromLocal, manipulatorState.m_localPosition, - cameraState, &m_shouldCorrect); + m_axis, m_cameraCorrectedAxis, managerState, mouseInteraction, manipulatorState.m_worldFromLocal, + manipulatorState.m_localPosition, cameraState, &m_shouldCorrect); CameraCorrectAxis( - m_offset, m_cameraCorrectedOffset, managerState, mouseInteraction, - manipulatorState.m_worldFromLocal, manipulatorState.m_localPosition, cameraState); + m_offset, m_cameraCorrectedOffset, managerState, mouseInteraction, manipulatorState.m_worldFromLocal, + manipulatorState.m_localPosition, cameraState); - const Picking::BoundShapeCone coneBound = - CalculateConeBound( - manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, m_cameraCorrectedAxis, - m_cameraCorrectedOffset * viewScale, - m_length * viewScale, - m_radius * viewScale); + const Picking::BoundShapeCone coneBound = CalculateConeBound( + manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, m_cameraCorrectedAxis, m_cameraCorrectedOffset * viewScale, + m_length * viewScale, m_radius * viewScale); debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_color, m_mouseOverColor).GetAsVector4()); if (m_shouldCorrect) @@ -460,73 +479,77 @@ namespace AzToolsFramework } void ManipulatorViewBox::Draw( - const ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + const ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + const ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) { - const float viewScale = ManipulatorViewScaleMultiplier( - manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState); + const float viewScale = + ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState); const AZ::Quaternion orientation = m_orientation; CameraCorrectAxis( - m_offset, m_cameraCorrectedOffset, managerState, mouseInteraction, - manipulatorState.m_worldFromLocal, manipulatorState.m_localPosition, - cameraState); + m_offset, m_cameraCorrectedOffset, managerState, mouseInteraction, manipulatorState.m_worldFromLocal, + manipulatorState.m_localPosition, cameraState); - const Picking::BoundShapeBox boxBound = - CalculateBoxBound(manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, orientation, - m_cameraCorrectedOffset * viewScale, - m_halfExtents * viewScale); + const Picking::BoundShapeBox boxBound = CalculateBoxBound( + manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, orientation, m_cameraCorrectedOffset * viewScale, + m_halfExtents * viewScale); const AZ::Vector3 xAxis = boxBound.m_orientation.TransformVector(AZ::Vector3::CreateAxisX()); const AZ::Vector3 yAxis = boxBound.m_orientation.TransformVector(AZ::Vector3::CreateAxisY()); const AZ::Vector3 zAxis = boxBound.m_orientation.TransformVector(AZ::Vector3::CreateAxisZ()); debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_color, m_mouseOverColor).GetAsVector4()); - debugDisplay.DrawSolidOBB(boxBound.m_center, - xAxis, yAxis, zAxis, boxBound.m_halfExtents); + debugDisplay.DrawSolidOBB(boxBound.m_center, xAxis, yAxis, zAxis, boxBound.m_halfExtents); RefreshBoundInternal(managerId, manipulatorId, boxBound); } void ManipulatorViewCylinder::Draw( - const ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + const ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + const ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) { - const float viewScale = ManipulatorViewScaleMultiplier( - manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState); + const float viewScale = + ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState); CameraCorrectAxis( - m_axis, m_cameraCorrectedAxis, managerState, mouseInteraction, - manipulatorState.m_worldFromLocal, manipulatorState.m_localPosition, cameraState); + m_axis, m_cameraCorrectedAxis, managerState, mouseInteraction, manipulatorState.m_worldFromLocal, + manipulatorState.m_localPosition, cameraState); - const Picking::BoundShapeCylinder cylinderBound = - CalculateCylinderBound( - manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, m_cameraCorrectedAxis, - m_length * viewScale, - m_radius * viewScale); + const Picking::BoundShapeCylinder cylinderBound = CalculateCylinderBound( + manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, m_cameraCorrectedAxis, m_length * viewScale, + m_radius * viewScale); debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_color, m_mouseOverColor).GetAsVector4()); - debugDisplay.DrawSolidCylinder(cylinderBound.m_base + cylinderBound.m_axis * cylinderBound.m_height * 0.5f, - cylinderBound.m_axis, cylinderBound.m_radius, cylinderBound.m_height, false); + debugDisplay.DrawSolidCylinder( + cylinderBound.m_base + cylinderBound.m_axis * cylinderBound.m_height * 0.5f, cylinderBound.m_axis, cylinderBound.m_radius, + cylinderBound.m_height, false); RefreshBoundInternal(managerId, manipulatorId, cylinderBound); } void ManipulatorViewSphere::Draw( - const ManipulatorManagerId managerId, const ManipulatorManagerState& /*managerState*/, - const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + const ManipulatorManagerId managerId, + const ManipulatorManagerState& /*managerState*/, + const ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) { - const Picking::BoundShapeSphere sphereBound = - CalculateSphereBound(manipulatorState.m_localPosition, manipulatorState, - m_radius * ManipulatorViewScaleMultiplier( - manipulatorState.TransformPoint(manipulatorState.m_localPosition), cameraState)); + const Picking::BoundShapeSphere sphereBound = CalculateSphereBound( + manipulatorState.m_localPosition, manipulatorState, + m_radius * ManipulatorViewScaleMultiplier(manipulatorState.TransformPoint(manipulatorState.m_localPosition), cameraState)); if (m_depthTest) { @@ -545,31 +568,32 @@ namespace AzToolsFramework } void ManipulatorViewCircle::Draw( - const ManipulatorManagerId managerId, const ManipulatorManagerState& /*managerState*/, - const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + const ManipulatorManagerId managerId, + const ManipulatorManagerState& /*managerState*/, + const ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& /*mouseInteraction*/) { - const float viewScale = ManipulatorViewScaleMultiplier( - manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState); + const float viewScale = + ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState); - const Picking::BoundShapeTorus torusBound = - CalculateTorusBound( - manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, m_axis, - m_radius * viewScale, - m_width * viewScale); + const Picking::BoundShapeTorus torusBound = CalculateTorusBound( + manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, m_axis, m_radius * viewScale, m_width * viewScale); // transform circle based on delta between default z up axis and other axes const AZ::Transform worldFromLocalWithOrientation = AZ::Transform::CreateTranslation(manipulatorState.m_worldFromLocal.GetTranslation()) * - AZ::Transform::CreateFromQuaternion( - (QuaternionFromTransformNoScaling(manipulatorState.m_worldFromLocal) * - AZ::Quaternion::CreateShortestArc(AZ::Vector3::CreateAxisZ(), m_axis)).GetNormalized()); + AZ::Transform::CreateFromQuaternion((QuaternionFromTransformNoScaling(manipulatorState.m_worldFromLocal) * + AZ::Quaternion::CreateShortestArc(AZ::Vector3::CreateAxisZ(), m_axis)) + .GetNormalized()); debugDisplay.CullOn(); debugDisplay.PushMatrix(worldFromLocalWithOrientation); debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_color, m_mouseOverColor).GetAsVector4()); - m_drawCircleFunc(debugDisplay, manipulatorState.m_localPosition, torusBound.m_majorRadius, + m_drawCircleFunc( + debugDisplay, manipulatorState.m_localPosition, torusBound.m_majorRadius, worldFromLocalWithOrientation.GetInverse().TransformPoint(cameraState.m_position)); debugDisplay.PopMatrix(); debugDisplay.CullOff(); @@ -578,27 +602,28 @@ namespace AzToolsFramework } void DrawHalfDottedCircle( - AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position, - const float radius, const AZ::Vector3& viewPos) + AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position, const float radius, const AZ::Vector3& viewPos) { debugDisplay.DrawHalfDottedCircle(position, radius, viewPos); } void DrawFullCircle( - AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position, - const float radius, const AZ::Vector3& /*viewPos*/) + AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position, const float radius, const AZ::Vector3& /*viewPos*/) { - debugDisplay.DrawCircle(position, radius); + debugDisplay.DrawCircle(position, radius); } void ManipulatorViewSplineSelect::Draw( - const ManipulatorManagerId managerId, const ManipulatorManagerState& /*managerState*/, - const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + const ManipulatorManagerId managerId, + const ManipulatorManagerState& /*managerState*/, + const ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) { - const float viewScale = ManipulatorViewScaleMultiplier( - manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState); + const float viewScale = + ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState); const Picking::BoundShapeSpline splineBound = CalculateSplineBound(m_spline, manipulatorState.m_worldFromLocal, m_width * viewScale); @@ -606,16 +631,15 @@ namespace AzToolsFramework if (manipulatorState.m_mouseOver) { const SplineSelectionManipulator::Action action = CalculateManipulationDataAction( - manipulatorState.m_worldFromLocal, mouseInteraction.m_mousePick.m_rayOrigin, - mouseInteraction.m_mousePick.m_rayDirection, m_spline); + manipulatorState.m_worldFromLocal, mouseInteraction.m_mousePick.m_rayOrigin, mouseInteraction.m_mousePick.m_rayDirection, + m_spline); - const AZ::Vector3 worldSplineHitPosition = - manipulatorState.m_worldFromLocal.TransformPoint(action.m_localSplineHitPosition); + const AZ::Vector3 worldSplineHitPosition = manipulatorState.m_worldFromLocal.TransformPoint(action.m_localSplineHitPosition); debugDisplay.SetColor(m_color.GetAsVector4()); debugDisplay.DrawBall( - worldSplineHitPosition, ManipulatorViewScaleMultiplier(worldSplineHitPosition, cameraState) - * g_defaultManipulatorSphereRadius, false); + worldSplineHitPosition, + ManipulatorViewScaleMultiplier(worldSplineHitPosition, cameraState) * g_defaultManipulatorSphereRadius, false); } RefreshBoundInternal(managerId, manipulatorId, splineBound); @@ -624,8 +648,7 @@ namespace AzToolsFramework /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AZStd::unique_ptr CreateManipulatorViewQuad( - const PlanarManipulator& planarManipulator, const AZ::Color& axis1Color, - const AZ::Color& axis2Color, const float size) + const PlanarManipulator& planarManipulator, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const float size) { AZStd::unique_ptr viewQuad = AZStd::make_unique(); viewQuad->m_axis1 = planarManipulator.GetAxis1(); @@ -636,8 +659,7 @@ namespace AzToolsFramework return viewQuad; } - AZStd::unique_ptr CreateManipulatorViewQuadBillboard( - const AZ::Color& color, const float size) + AZStd::unique_ptr CreateManipulatorViewQuadBillboard(const AZ::Color& color, const float size) { AZStd::unique_ptr viewQuad = AZStd::make_unique(); viewQuad->m_size = size; @@ -646,8 +668,7 @@ namespace AzToolsFramework } AZStd::unique_ptr CreateManipulatorViewLine( - const LinearManipulator& linearManipulator, const AZ::Color& color, - const float length, const float width) + const LinearManipulator& linearManipulator, const AZ::Color& color, const float length, const float width) { AZStd::unique_ptr viewLine = AZStd::make_unique(); viewLine->m_axis = linearManipulator.GetAxis(); @@ -658,8 +679,7 @@ namespace AzToolsFramework } AZStd::unique_ptr CreateManipulatorViewLineSelect( - const LineSegmentSelectionManipulator& lineSegmentManipulator, - const AZ::Color& color, const float width) + const LineSegmentSelectionManipulator& lineSegmentManipulator, const AZ::Color& color, const float width) { AZStd::unique_ptr viewLineSelect = AZStd::make_unique(); viewLineSelect->m_localStart = lineSegmentManipulator.GetStart(); @@ -670,8 +690,11 @@ namespace AzToolsFramework } AZStd::unique_ptr CreateManipulatorViewCone( - const LinearManipulator& linearManipulator, const AZ::Color& color, - const AZ::Vector3& offset, const float length, const float radius) + const LinearManipulator& linearManipulator, + const AZ::Color& color, + const AZ::Vector3& offset, + const float length, + const float radius) { AZStd::unique_ptr viewCone = AZStd::make_unique(); viewCone->m_axis = linearManipulator.GetAxis(); @@ -683,8 +706,7 @@ namespace AzToolsFramework } AZStd::unique_ptr CreateManipulatorViewBox( - const AZ::Transform& transform, const AZ::Color& color, - const AZ::Vector3& offset, const AZ::Vector3& halfExtents) + const AZ::Transform& transform, const AZ::Color& color, const AZ::Vector3& offset, const AZ::Vector3& halfExtents) { AZStd::unique_ptr viewBox = AZStd::make_unique(); viewBox->m_orientation = transform.GetRotation(); @@ -695,8 +717,7 @@ namespace AzToolsFramework } AZStd::unique_ptr CreateManipulatorViewCylinder( - const LinearManipulator& linearManipulator, const AZ::Color& color, - const float length, const float radius) + const LinearManipulator& linearManipulator, const AZ::Color& color, const float length, const float radius) { AZStd::unique_ptr viewCylinder = AZStd::make_unique(); viewCylinder->m_axis = linearManipulator.GetAxis(); @@ -718,8 +739,11 @@ namespace AzToolsFramework } AZStd::unique_ptr CreateManipulatorViewCircle( - const AngularManipulator& angularManipulator, const AZ::Color& color, - const float radius, const float width, const ManipulatorViewCircle::DrawCircleFunc drawFunc) + const AngularManipulator& angularManipulator, + const AZ::Color& color, + const float radius, + const float width, + const ManipulatorViewCircle::DrawCircleFunc drawFunc) { AZStd::unique_ptr viewCircle = AZStd::make_unique(); viewCircle->m_axis = angularManipulator.GetAxis(); @@ -731,8 +755,7 @@ namespace AzToolsFramework } AZStd::unique_ptr CreateManipulatorViewSplineSelect( - const SplineSelectionManipulator& splineManipulator, - const AZ::Color& color, const float width) + const SplineSelectionManipulator& splineManipulator, const AZ::Color& color, const float width) { AZStd::unique_ptr viewSplineSelect = AZStd::make_unique(); viewSplineSelect->m_spline = splineManipulator.GetSpline(); @@ -741,16 +764,12 @@ namespace AzToolsFramework return viewSplineSelect; } - AZ::Vector3 CalculateViewDirection( - const Manipulators& manipulators, const AZ::Vector3& worldViewPosition) + AZ::Vector3 CalculateViewDirection(const Manipulators& manipulators, const AZ::Vector3& worldViewPosition) { - const AZ::Transform worldFromLocalWithTransform = - manipulators.GetSpace() * manipulators.GetLocalTransform(); + const AZ::Transform worldFromLocalWithTransform = manipulators.GetSpace() * manipulators.GetLocalTransform(); - AZ::Vector3 lookDirection = - (worldFromLocalWithTransform.GetTranslation() - worldViewPosition).GetNormalized(); + AZ::Vector3 lookDirection = (worldFromLocalWithTransform.GetTranslation() - worldViewPosition).GetNormalized(); - return TransformDirectionNoScaling( - worldFromLocalWithTransform.GetInverse(), lookDirection); + return TransformDirectionNoScaling(worldFromLocalWithTransform.GetInverse(), lookDirection); } } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.h index da426d2340..8573f8ce32 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -26,13 +26,12 @@ namespace AzToolsFramework class LineSegmentSelectionManipulator; class SplineSelectionManipulator; - using DecideColorFn = AZStd::function; + using DecideColorFn = + AZStd::function; extern const float g_defaultManipulatorSphereRadius; - /// State of an individual manipulator. + //! State of an individual manipulator. struct ManipulatorState { AZ::Transform m_worldFromLocal; @@ -40,18 +39,18 @@ namespace AzToolsFramework AZ::Vector3 m_localPosition; bool m_mouseOver; - /// Transforms a point, taking non-uniform scale into account. + //! Transforms a point, taking non-uniform scale into account. AZ::Vector3 TransformPoint(const AZ::Vector3& point) const; - /// Rotates a direction into the space of the manipulator and normalizes it. - /// Non-uniform scaling and translation are not applied. + //! Rotates a direction into the space of the manipulator and normalizes it. + //! Non-uniform scaling and translation are not applied. AZ::Vector3 TransformDirectionNoScaling(const AZ::Vector3& direction) const; }; - /// The base interface for the visual representation of manipulators. - /// The View represents the appearance and bounds of the manipulator for - /// the user to interact with. Any manipulator can have any view (some may - /// be more appropriate than others in certain cases). + //! The base interface for the visual representation of manipulators. + //! The View represents the appearance and bounds of the manipulator for + //! the user to interact with. Any manipulator can have any view (some may + //! be more appropriate than others in certain cases). class ManipulatorView { public: @@ -65,98 +64,107 @@ namespace AzToolsFramework ManipulatorView& operator=(ManipulatorView&&) = default; void SetBoundDirty(ManipulatorManagerId managerId); - void RefreshBound( - ManipulatorManagerId managerId, ManipulatorId manipulatorId, const Picking::BoundRequestShapeBase& bound); + void RefreshBound(ManipulatorManagerId managerId, ManipulatorId manipulatorId, const Picking::BoundRequestShapeBase& bound); void Invalidate(ManipulatorManagerId managerId); virtual void Draw( - ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) = 0; - bool ScreenSizeFixed() const { return m_screenSizeFixed; } + bool ScreenSizeFixed() const + { + return m_screenSizeFixed; + } protected: - AZ::Color m_mouseOverColor = BaseManipulator::s_defaultMouseOverColor; ///< What color should the manipulator - ///< be when the mouse is hovering over it. - /// Scale the manipulator based on the distance - /// from the camera if m_screenSizeFixed is true. - float ManipulatorViewScaleMultiplier( - const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState) const; - - /// Wrap the logic for updating a bound. - /// Should be called at the end of the Draw function once a concrete BoundRequestShape has - /// been created to use for dimensions for rendering. - void RefreshBoundInternal( - ManipulatorManagerId managerId, ManipulatorId manipulatorId, const Picking::BoundRequestShapeBase& bound); + AZ::Color m_mouseOverColor = BaseManipulator::s_defaultMouseOverColor; //!< What color should the manipulator + //!< be when the mouse is hovering over it. + //! Scale the manipulator based on the distance + //! from the camera if m_screenSizeFixed is true. + float ManipulatorViewScaleMultiplier(const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState) const; + + //! Wrap the logic for updating a bound. + //! Should be called at the end of the Draw function once a concrete BoundRequestShape has + //! been created to use for dimensions for rendering. + void RefreshBoundInternal(ManipulatorManagerId managerId, ManipulatorId manipulatorId, const Picking::BoundRequestShapeBase& bound); private: - Picking::RegisteredBoundId m_boundId = Picking::InvalidBoundId; ///< Used for hit detection. - ManipulatorManagerId m_managerId = InvalidManipulatorManagerId; /// The manipulator manager this view has been registered with. - bool m_screenSizeFixed = true; ///< Should manipulator size be adjusted based on camera distance. - bool m_boundDirty = true; ///< Do the bounds need to be recalculated. + Picking::RegisteredBoundId m_boundId = Picking::InvalidBoundId; //!< Used for hit detection. + ManipulatorManagerId m_managerId = InvalidManipulatorManagerId; //! The manipulator manager this view has been registered with. + bool m_screenSizeFixed = true; //!< Should manipulator size be adjusted based on camera distance. + bool m_boundDirty = true; //!< Do the bounds need to be recalculated. }; // A collection of views (a manipulator may have 1 - * views) using ManipulatorViews = AZStd::vector>; - /// Display a quad representing part of a plane, rendered as 4 lines. - class ManipulatorViewQuad - : public ManipulatorView + //! Display a quad representing part of a plane, rendered as 4 lines. + class ManipulatorViewQuad : public ManipulatorView { public: AZ_CLASS_ALLOCATOR(ManipulatorViewQuad, AZ::SystemAllocator, 0) AZ_RTTI(ManipulatorViewQuad, "{D85E1B45-495E-4755-BCF2-6AE45F8BB2B0}", ManipulatorView) void Draw( - ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) override; AZ::Vector3 m_axis1 = AZ::Vector3(1.0f, 0.0f, 0.0f); AZ::Vector3 m_axis2 = AZ::Vector3(0.0f, 1.0f, 0.0f); AZ::Color m_axis1Color = AZ::Color(1.0f, 0.0f, 0.0f, 1.0f); AZ::Color m_axis2Color = AZ::Color(1.0f, 0.0f, 0.0f, 1.0f); - float m_size = 0.06f; ///< size to render and do mouse ray intersection tests against. + float m_size = 0.06f; //!< size to render and do mouse ray intersection tests against. private: AZ::Vector3 m_cameraCorrectedAxis1; AZ::Vector3 m_cameraCorrectedAxis2; }; - /// A screen aligned quad, centered at the position of the manipulator, display filled. - class ManipulatorViewQuadBillboard - : public ManipulatorView + //! A screen aligned quad, centered at the position of the manipulator, display filled. + class ManipulatorViewQuadBillboard : public ManipulatorView { public: AZ_CLASS_ALLOCATOR(ManipulatorViewQuadBillboard, AZ::SystemAllocator, 0) AZ_RTTI(ManipulatorViewQuadBillboard, "{C205E967-E8C6-4A73-A31B-41EE5529B15B}", ManipulatorView) void Draw( - ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) override; AZ::Color m_color = AZ::Color(1.0f, 0.0f, 0.0f, 1.0f); - float m_size = 0.005f; ///< size to render and do mouse ray intersection tests against. + float m_size = 0.005f; //!< size to render and do mouse ray intersection tests against. }; - /// Displays a debug style line starting from the manipulator's transform, - /// width determines the click area. - class ManipulatorViewLine - : public ManipulatorView + //! Displays a debug style line starting from the manipulator's transform, + //! width determines the click area. + class ManipulatorViewLine : public ManipulatorView { public: AZ_CLASS_ALLOCATOR(ManipulatorViewLine, AZ::SystemAllocator, 0) AZ_RTTI(ManipulatorViewLine, "{831EEF66-4A5C-450C-B152-EA4A0BC8A272}", ManipulatorView) void Draw( - ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) override; AZ::Vector3 m_axis; @@ -168,19 +176,21 @@ namespace AzToolsFramework AZ::Vector3 m_cameraCorrectedAxis; }; - /// Variant of ManipulatorViewLine which instead of using an axis, provides begin and end - /// points for the line. Used for selection when inserting points along a line. - class ManipulatorViewLineSelect - : public ManipulatorView + //! Variant of ManipulatorViewLine which instead of using an axis, provides begin and end + //! points for the line. Used for selection when inserting points along a line. + class ManipulatorViewLineSelect : public ManipulatorView { public: AZ_CLASS_ALLOCATOR(ManipulatorViewLineSelect, AZ::SystemAllocator, 0) AZ_RTTI(ManipulatorViewLineSelect, "{BF26A947-91F8-4595-9A5B-481876EB2C48}", ManipulatorView) void Draw( - ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) override; AZ::Vector3 m_localStart; @@ -189,20 +199,22 @@ namespace AzToolsFramework float m_width = 0.0f; }; - /// Displays a filled cone along the specified axis, offset is local translation from - /// the manipulator transform (often used in conjunction with other views to build - /// aggregate views such as arrows - e.g. a line and cone). - class ManipulatorViewCone - : public ManipulatorView + //! Displays a filled cone along the specified axis, offset is local translation from + //! the manipulator transform (often used in conjunction with other views to build + //! aggregate views such as arrows - e.g. a line and cone). + class ManipulatorViewCone : public ManipulatorView { public: AZ_CLASS_ALLOCATOR(ManipulatorViewCone, AZ::SystemAllocator, 0) AZ_RTTI(ManipulatorViewCone, "{BF042887-1F51-4FD8-8CA5-4A649B4AF356}", ManipulatorView) void Draw( - ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) override; AZ::Vector3 m_offset; @@ -217,20 +229,22 @@ namespace AzToolsFramework bool m_shouldCorrect = false; }; - /// Displays a filled box, offset is local translation from the manipulator - /// transform, box is often used in conjunction with other views, orientation allows - /// the box to be orientated separately from the manipulator transform. - class ManipulatorViewBox - : public ManipulatorView + //! Displays a filled box, offset is local translation from the manipulator + //! transform, box is often used in conjunction with other views, orientation allows + //! the box to be orientated separately from the manipulator transform. + class ManipulatorViewBox : public ManipulatorView { public: AZ_CLASS_ALLOCATOR(ManipulatorViewBox, AZ::SystemAllocator, 0) AZ_RTTI(ManipulatorViewBox, "{2D082201-7878-4C1B-A3DD-7A629E5AD598}", ManipulatorView) void Draw( - ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) override; AZ::Vector3 m_offset; @@ -242,18 +256,20 @@ namespace AzToolsFramework AZ::Vector3 m_cameraCorrectedOffset; }; - /// Displays a filled cylinder along the axis provided. - class ManipulatorViewCylinder - : public ManipulatorView + //! Displays a filled cylinder along the axis provided. + class ManipulatorViewCylinder : public ManipulatorView { public: AZ_CLASS_ALLOCATOR(ManipulatorViewCylinder, AZ::SystemAllocator, 0) AZ_RTTI(ManipulatorViewCylinder, "{9B8E5EF4-0F85-4CD0-A5FF-3C7097DF58AC}", ManipulatorView) void Draw( - ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) override; AZ::Vector3 m_axis; @@ -265,20 +281,22 @@ namespace AzToolsFramework AZ::Vector3 m_cameraCorrectedAxis; }; - /// Displays a filled sphere at the transform of the manipulator, often used as - /// a selection manipulator. DecideColorFn allows more complex logic to be used - /// to decide the color of the manipulator (based on hover state etc.) - class ManipulatorViewSphere - : public ManipulatorView + //! Displays a filled sphere at the transform of the manipulator, often used as + //! a selection manipulator. DecideColorFn allows more complex logic to be used + //! to decide the color of the manipulator (based on hover state etc.) + class ManipulatorViewSphere : public ManipulatorView { public: AZ_CLASS_ALLOCATOR(ManipulatorViewSphere, AZ::SystemAllocator, 0) AZ_RTTI(ManipulatorViewSphere, "{324D8329-6E7B-4A5D-AC8A-8C0E1C984E38}", ManipulatorView) void Draw( - ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) override; float m_radius = 0.0f; @@ -287,23 +305,24 @@ namespace AzToolsFramework bool m_depthTest = false; }; - /// Displays a wire circle. DrawCircleFunc can be used to either draw a full - /// circle or a half dotted circle where the part of the circle facing away - /// from the camera is dotted (useful for angular/rotation manipulators). - class ManipulatorViewCircle - : public ManipulatorView + //! Displays a wire circle. DrawCircleFunc can be used to either draw a full + //! circle or a half dotted circle where the part of the circle facing away + //! from the camera is dotted (useful for angular/rotation manipulators). + class ManipulatorViewCircle : public ManipulatorView { public: AZ_CLASS_ALLOCATOR(ManipulatorViewCircle, AZ::SystemAllocator, 0) AZ_RTTI(ManipulatorViewCircle, "{26563A03-3E48-49EB-9DCF-30EE4F567FCD}", ManipulatorView) - using DrawCircleFunc = - void(*)(AzFramework::DebugDisplayRequests&, const AZ::Vector3&, float, const AZ::Vector3&); + using DrawCircleFunc = void (*)(AzFramework::DebugDisplayRequests&, const AZ::Vector3&, float, const AZ::Vector3&); void Draw( - ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) override; AZ::Vector3 m_axis; @@ -316,26 +335,26 @@ namespace AzToolsFramework // helpers to provide consistent function pointer interface for deciding // on type of circle to draw (see DrawCircleFunc in ManipulatorViewCircle above) void DrawHalfDottedCircle( - AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position, - float radius, const AZ::Vector3& viewPos); + AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position, float radius, const AZ::Vector3& viewPos); void DrawFullCircle( - AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position, - float radius, const AZ::Vector3& viewPos); - - /// Used for interaction with spline primitive - it will generate a spline bound - /// to be interacted with and will display the intersection point on the spline - /// where a user may wish to insert a point. - class ManipulatorViewSplineSelect - : public ManipulatorView + AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position, float radius, const AZ::Vector3& viewPos); + + //! Used for interaction with spline primitive - it will generate a spline bound + //! to be interacted with and will display the intersection point on the spline + //! where a user may wish to insert a point. + class ManipulatorViewSplineSelect : public ManipulatorView { public: AZ_CLASS_ALLOCATOR(ManipulatorViewSplineSelect, AZ::SystemAllocator, 0) AZ_RTTI(ManipulatorViewSplineSelect, "{60996E49-D6BF-4817-BAA3-D27A407DD21A}", ManipulatorView) void Draw( - ManipulatorManagerId managerId, const ManipulatorManagerState& managerState, - ManipulatorId manipulatorId, const ManipulatorState& manipulatorState, - AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState, + ManipulatorManagerId managerId, + const ManipulatorManagerState& managerState, + ManipulatorId manipulatorId, + const ManipulatorState& manipulatorState, + AzFramework::DebugDisplayRequests& debugDisplay, + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) override; AZStd::weak_ptr m_spline; @@ -343,65 +362,61 @@ namespace AzToolsFramework AZ::Color m_color = AZ::Color(0.0f, 1.0f, 0.0f, 1.0f); }; - /// Returns true if axis is pointing away from us (we should flip it). + //! Returns true if axis is pointing away from us (we should flip it). inline bool ShouldFlipCameraAxis( - const AZ::Transform& worldFromLocal, const AZ::Vector3& localPosition, - const AZ::Vector3& axis, const AzFramework::CameraState& cameraState) + const AZ::Transform& worldFromLocal, + const AZ::Vector3& localPosition, + const AZ::Vector3& axis, + const AzFramework::CameraState& cameraState) { - return (worldFromLocal.TransformPoint(localPosition) - cameraState.m_position).Dot( - TransformDirectionNoScaling(worldFromLocal, axis)) > 0.0f; + return (worldFromLocal.TransformPoint(localPosition) - cameraState.m_position) + .Dot(TransformDirectionNoScaling(worldFromLocal, axis)) > 0.0f; } - /// @brief Return the world transform of the entity with uniform scale - choose - /// the largest element. + //! @brief Return the world transform of the entity with uniform scale - choose + //! the largest element. AZ::Transform WorldFromLocalWithUniformScale(AZ::EntityId entityId); - /// Get the non-uniform scale for this entity id. + //! Get the non-uniform scale for this entity id. AZ::Vector3 GetNonUniformScale(AZ::EntityId entityId); // Helpers to create various manipulator views. AZStd::unique_ptr CreateManipulatorViewQuad( - const PlanarManipulator& planarManipulator, const AZ::Color& axis1Color, - const AZ::Color& axis2Color, float size); + const PlanarManipulator& planarManipulator, const AZ::Color& axis1Color, const AZ::Color& axis2Color, float size); - AZStd::unique_ptr CreateManipulatorViewQuadBillboard( - const AZ::Color& color, float size); + AZStd::unique_ptr CreateManipulatorViewQuadBillboard(const AZ::Color& color, float size); AZStd::unique_ptr CreateManipulatorViewLine( - const LinearManipulator& linearManipulator, const AZ::Color& color, - float length, float width); + const LinearManipulator& linearManipulator, const AZ::Color& color, float length, float width); AZStd::unique_ptr CreateManipulatorViewLineSelect( - const LineSegmentSelectionManipulator& lineSegmentManipulator, const AZ::Color& color, - float width); + const LineSegmentSelectionManipulator& lineSegmentManipulator, const AZ::Color& color, float width); AZStd::unique_ptr CreateManipulatorViewCone( - const LinearManipulator& linearManipulator, const AZ::Color& color, - const AZ::Vector3& offset, float length, float radius); + const LinearManipulator& linearManipulator, const AZ::Color& color, const AZ::Vector3& offset, float length, float radius); AZStd::unique_ptr CreateManipulatorViewBox( - const AZ::Transform& transform, const AZ::Color& color, - const AZ::Vector3& offset, const AZ::Vector3& halfExtents); + const AZ::Transform& transform, const AZ::Color& color, const AZ::Vector3& offset, const AZ::Vector3& halfExtents); AZStd::unique_ptr CreateManipulatorViewCylinder( - const LinearManipulator& linearManipulator, const AZ::Color& color, - float length, float radius); + const LinearManipulator& linearManipulator, const AZ::Color& color, float length, float radius); AZStd::unique_ptr CreateManipulatorViewSphere( const AZ::Color& color, float radius, const DecideColorFn& decideColor, bool enableDepthTest = false); AZStd::unique_ptr CreateManipulatorViewCircle( - const AngularManipulator& angularManipulator, const AZ::Color& color, - float radius, float width, ManipulatorViewCircle::DrawCircleFunc drawFunc); + const AngularManipulator& angularManipulator, + const AZ::Color& color, + float radius, + float width, + ManipulatorViewCircle::DrawCircleFunc drawFunc); AZStd::unique_ptr CreateManipulatorViewSplineSelect( - const SplineSelectionManipulator& splineManipulator, const AZ::Color& color, - float width); + const SplineSelectionManipulator& splineManipulator, const AZ::Color& color, float width); - /// Returns the vector between the view (camera) and the manipulator in the space - /// of the Manipulator (manipulator space + local transform). - AZ::Vector3 CalculateViewDirection( - const Manipulators& manipulators, const AZ::Vector3& worldViewPosition); + //! Returns the vector between the view (camera) and the manipulator in the space + //! of the Manipulator (manipulator space + local transform). + AZ::Vector3 CalculateViewDirection(const Manipulators& manipulators, const AZ::Vector3& worldViewPosition); } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/MultiLinearManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/MultiLinearManipulator.cpp index 83c4c28e9a..922ac95bf7 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/MultiLinearManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/MultiLinearManipulator.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "MultiLinearManipulator.h" @@ -56,10 +56,13 @@ namespace AzToolsFramework } static MultiLinearManipulator::Action BuildMultiLinearManipulatorAction( - const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Transform& localTransform, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& nonUniformScale, + const AZ::Transform& localTransform, const ViewportInteraction::MouseInteraction& interaction, const AZStd::vector& fixedAxes, - const AZStd::vector& starterStates, const GridSnapParameters& gridSnapParams) + const AZStd::vector& starterStates, + const GridSnapParameters& gridSnapParams) { MultiLinearManipulator::Action action; action.m_viewportId = interaction.m_interactionId.m_viewportId; @@ -96,8 +99,8 @@ namespace AzToolsFramework const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId); // pass action containing all linear actions for each axis to handler m_onLeftMouseDownCallback(BuildMultiLinearManipulatorAction( - worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(), - interaction, m_fixedAxes, m_starters, gridSnapParams)); + worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(), interaction, m_fixedAxes, m_starters, + gridSnapParams)); } } @@ -108,8 +111,8 @@ namespace AzToolsFramework const AZ::Transform worldFromLocalUniformScale = TransformUniformScale(GetSpace()); const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId); m_onMouseMoveCallback(BuildMultiLinearManipulatorAction( - worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(), - interaction, m_fixedAxes, m_starters, gridSnapParams)); + worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(), interaction, m_fixedAxes, m_starters, + gridSnapParams)); } } @@ -120,8 +123,8 @@ namespace AzToolsFramework const AZ::Transform worldFromLocalUniformScale = TransformUniformScale(GetSpace()); const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId); m_onLeftMouseUpCallback(BuildMultiLinearManipulatorAction( - worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(), - interaction, m_fixedAxes, m_starters, gridSnapParams)); + worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(), interaction, m_fixedAxes, m_starters, + gridSnapParams)); m_starters.clear(); } @@ -138,36 +141,31 @@ namespace AzToolsFramework const AZ::Transform combined = TransformUniformScale(GetSpace()) * GetLocalTransform(); for (const auto& fixed : m_fixedAxes) { - DrawAxis( - debugDisplay, combined.GetTranslation(), TransformDirectionNoScaling(combined, fixed.m_axis)); + DrawAxis(debugDisplay, combined.GetTranslation(), TransformDirectionNoScaling(combined, fixed.m_axis)); } } for (auto& view : m_manipulatorViews) { view->Draw( - GetManipulatorManagerId(), managerState, - GetManipulatorId(), { - ApplySpace(GetLocalTransform()), GetNonUniformScale(), - AZ::Vector3::CreateZero(), MouseOver() - }, - debugDisplay, cameraState, mouseInteraction); + GetManipulatorManagerId(), managerState, GetManipulatorId(), + { ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, + cameraState, mouseInteraction); } } void MultiLinearManipulator::AddAxis(const AZ::Vector3& axis) { - m_fixedAxes.push_back(LinearManipulator::Fixed{axis}); + m_fixedAxes.push_back(LinearManipulator::Fixed{ axis }); } void MultiLinearManipulator::AddAxes(const AZStd::vector& axes) { AZStd::transform( - axes.begin(), axes.end(), - AZStd::back_inserter(m_fixedAxes), + axes.begin(), axes.end(), AZStd::back_inserter(m_fixedAxes), [](const AZ::Vector3& axis) { - return LinearManipulator::Fixed{axis}; + return LinearManipulator::Fixed{ axis }; }); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/MultiLinearManipulator.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/MultiLinearManipulator.h index 8e31e02605..7cae803dfa 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/MultiLinearManipulator.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/MultiLinearManipulator.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -80,12 +80,9 @@ namespace AzToolsFramework } private: - void OnLeftMouseDownImpl( - const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; - void OnLeftMouseUpImpl( - const ViewportInteraction::MouseInteraction& interaction) override; - void OnMouseMoveImpl( - const ViewportInteraction::MouseInteraction& interaction) override; + void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; + void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override; + void OnMouseMoveImpl(const ViewportInteraction::MouseInteraction& interaction) override; void InvalidateImpl() override; void SetBoundsDirtyImpl() override; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/PlanarManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/PlanarManipulator.cpp index 6eb96f081c..f146ca4430 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/PlanarManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/PlanarManipulator.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "PlanarManipulator.h" @@ -22,12 +22,15 @@ namespace AzToolsFramework { PlanarManipulator::StartInternal PlanarManipulator::CalculateManipulationDataStart( - const Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Transform& localTransform, - const ViewportInteraction::MouseInteraction& interaction, const float intersectionDistance) + const Fixed& fixed, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& nonUniformScale, + const AZ::Transform& localTransform, + const ViewportInteraction::MouseInteraction& interaction, + const float intersectionDistance) { - const ManipulatorInteraction manipulatorInteraction = - BuildManipulatorInteraction( - worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection); + const ManipulatorInteraction manipulatorInteraction = BuildManipulatorInteraction( + worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection); const AZ::Vector3 normal = TransformDirectionNoScaling(localTransform, fixed.m_normal); @@ -37,8 +40,8 @@ namespace AzToolsFramework StartInternal startInternal; Internal::CalculateRayPlaneIntersectingPoint( - manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection, - localIntersectionPoint, normal, startInternal.m_localHitPosition); + manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection, localIntersectionPoint, normal, + startInternal.m_localHitPosition); startInternal.m_localPosition = localTransform.GetTranslation(); @@ -46,13 +49,16 @@ namespace AzToolsFramework } PlanarManipulator::Action PlanarManipulator::CalculateManipulationDataAction( - const Fixed& fixed, const StartInternal& startInternal, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, - const AZ::Transform& localTransform, const GridSnapParameters& gridSnapParams, + const Fixed& fixed, + const StartInternal& startInternal, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& nonUniformScale, + const AZ::Transform& localTransform, + const GridSnapParameters& gridSnapParams, const ViewportInteraction::MouseInteraction& interaction) { - const ManipulatorInteraction manipulatorInteraction = - BuildManipulatorInteraction( - worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection); + const ManipulatorInteraction manipulatorInteraction = BuildManipulatorInteraction( + worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection); const AZ::Vector3 normal = TransformDirectionNoScaling(localTransform, fixed.m_normal); @@ -61,8 +67,8 @@ namespace AzToolsFramework // if an invalid ray intersection is attempted AZ::Vector3 localHitPosition = startInternal.m_localHitPosition; Internal::CalculateRayPlaneIntersectingPoint( - manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection, - startInternal.m_localHitPosition, normal, localHitPosition); + manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection, startInternal.m_localHitPosition, normal, + localHitPosition); localHitPosition = Internal::TryConstrainHitPositionToView( localHitPosition, startInternal.m_localHitPosition, worldFromLocal.GetInverse(), @@ -126,8 +132,8 @@ namespace AzToolsFramework const AZ::Transform worldFromLocalUniformScale = TransformUniformScale(GetSpace()); m_startInternal = CalculateManipulationDataStart( - m_fixed, worldFromLocalUniformScale, GetNonUniformScale(), TransformNormalizedScale(GetLocalTransform()), - interaction, rayIntersectionDistance); + m_fixed, worldFromLocalUniformScale, GetNonUniformScale(), TransformNormalizedScale(GetLocalTransform()), interaction, + rayIntersectionDistance); if (m_onLeftMouseDownCallback) { @@ -180,9 +186,10 @@ namespace AzToolsFramework // display the exact hit (ray intersection) of the mouse pick on the manipulator DrawTransformAxes( - debugDisplay, TransformUniformScale(GetSpace()) * - AZ::Transform::CreateTranslation( - action.m_start.m_localHitPosition + GetNonUniformScale() * action.m_current.m_localOffset)); + debugDisplay, + TransformUniformScale(GetSpace()) * + AZ::Transform::CreateTranslation( + action.m_start.m_localHitPosition + GetNonUniformScale() * action.m_current.m_localOffset)); } AZ::Transform combined = GetLocalTransform(); @@ -191,23 +198,16 @@ namespace AzToolsFramework DrawTransformAxes(debugDisplay, combined); - DrawAxis( - debugDisplay, combined.GetTranslation(), - TransformDirectionNoScaling(GetLocalTransform(), m_fixed.m_axis1)); - DrawAxis( - debugDisplay, combined.GetTranslation(), - TransformDirectionNoScaling(GetLocalTransform(), m_fixed.m_axis2)); + DrawAxis(debugDisplay, combined.GetTranslation(), TransformDirectionNoScaling(GetLocalTransform(), m_fixed.m_axis1)); + DrawAxis(debugDisplay, combined.GetTranslation(), TransformDirectionNoScaling(GetLocalTransform(), m_fixed.m_axis2)); } for (auto& view : m_manipulatorViews) { view->Draw( - GetManipulatorManagerId(), managerState, - GetManipulatorId(), { - ApplySpace(GetLocalTransform()), GetNonUniformScale(), - AZ::Vector3::CreateZero(), MouseOver() - }, - debugDisplay, cameraState, mouseInteraction); + GetManipulatorManagerId(), managerState, GetManipulatorId(), + { ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, + cameraState, mouseInteraction); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/PlanarManipulator.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/PlanarManipulator.h index 154ed4c7d6..3bd028ec0a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/PlanarManipulator.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/PlanarManipulator.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -23,13 +23,13 @@ namespace AzToolsFramework class ManipulatorView; struct GridSnapParameters; - /// PlanarManipulator serves as a visual tool for users to modify values - /// in two dimension in a plane defined two non-collinear axes in 3D space. + //! PlanarManipulator serves as a visual tool for users to modify values + //! in two dimension in a plane defined two non-collinear axes in 3D space. class PlanarManipulator : public BaseManipulator , public ManipulatorSpaceWithLocalTransform { - /// Private constructor. + //! Private constructor. explicit PlanarManipulator(const AZ::Transform& worldFromLocal); public: @@ -42,43 +42,51 @@ namespace AzToolsFramework ~PlanarManipulator() = default; - /// A Manipulator must only be created and managed through a shared_ptr. + //! A Manipulator must only be created and managed through a shared_ptr. static AZStd::shared_ptr MakeShared(const AZ::Transform& worldFromLocal); - /// Unchanging data set once for the planar manipulator. + //! Unchanging data set once for the planar manipulator. struct Fixed { - AZ::Vector3 m_axis1 = AZ::Vector3::CreateAxisX(); ///< m_axis1 and m_axis2 have to be orthogonal, they together define a plane in 3d space. + AZ::Vector3 m_axis1 = + AZ::Vector3::CreateAxisX(); //!< m_axis1 and m_axis2 have to be orthogonal, they together define a plane in 3d space. AZ::Vector3 m_axis2 = AZ::Vector3::CreateAxisY(); - AZ::Vector3 m_normal = AZ::Vector3::CreateAxisZ(); ///< m_normal is calculated automatically when setting the axes. + AZ::Vector3 m_normal = AZ::Vector3::CreateAxisZ(); //!< m_normal is calculated automatically when setting the axes. }; - /// The state of the manipulator at the start of an interaction. + //! The state of the manipulator at the start of an interaction. struct Start { - AZ::Vector3 m_localPosition; ///< The current position of the manipulator in local space. - AZ::Vector3 m_localHitPosition; ///< The intersection point in local space between the ray and the manipulator when the mouse down event happens. + AZ::Vector3 m_localPosition; //!< The current position of the manipulator in local space. + AZ::Vector3 m_localHitPosition; //!< The intersection point in local space between the ray and the manipulator when the mouse + //!< down event happens. }; - /// The state of the manipulator during an interaction. + //! The state of the manipulator during an interaction. struct Current { - AZ::Vector3 m_localOffset; ///< The current position of the manipulator in local space. + AZ::Vector3 m_localOffset; //!< The current position of the manipulator in local space. }; - /// Mouse action data used by MouseActionCallback (wraps Start and Current manipulator state). + //! Mouse action data used by MouseActionCallback (wraps Start and Current manipulator state). struct Action { Fixed m_fixed; Start m_start; Current m_current; ViewportInteraction::KeyboardModifiers m_modifiers; - AZ::Vector3 LocalPosition() const { return m_start.m_localPosition + m_current.m_localOffset; } - AZ::Vector3 LocalPositionOffset() const { return m_current.m_localOffset; } + AZ::Vector3 LocalPosition() const + { + return m_start.m_localPosition + m_current.m_localOffset; + } + AZ::Vector3 LocalPositionOffset() const + { + return m_current.m_localOffset; + } }; - /// This is the function signature of callbacks that will be invoked whenever a manipulator - /// is being clicked on or dragged. + //! This is the function signature of callbacks that will be invoked whenever a manipulator + //! is being clicked on or dragged. using MouseActionCallback = AZStd::function; void InstallLeftMouseDownCallback(const MouseActionCallback& onMouseDownCallback); @@ -91,11 +99,17 @@ namespace AzToolsFramework const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) override; - /// Ensure @param axis1 and @param axis2 are not collinear. + //! Ensure @param axis1 and @param axis2 are not collinear. void SetAxes(const AZ::Vector3& axis1, const AZ::Vector3& axis2); - const AZ::Vector3& GetAxis1() const { return m_fixed.m_axis1; } - const AZ::Vector3& GetAxis2() const { return m_fixed.m_axis2; } + const AZ::Vector3& GetAxis1() const + { + return m_fixed.m_axis1; + } + const AZ::Vector3& GetAxis2() const + { + return m_fixed.m_axis2; + } template void SetViews(Views&& views) @@ -104,21 +118,19 @@ namespace AzToolsFramework } private: - void OnLeftMouseDownImpl( - const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; - void OnLeftMouseUpImpl( - const ViewportInteraction::MouseInteraction& interaction) override; - void OnMouseMoveImpl( - const ViewportInteraction::MouseInteraction& interaction) override; + void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; + void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override; + void OnMouseMoveImpl(const ViewportInteraction::MouseInteraction& interaction) override; void InvalidateImpl() override; void SetBoundsDirtyImpl() override; - /// Initial data recorded when a press first happens with a planar manipulator. + //! Initial data recorded when a press first happens with a planar manipulator. struct StartInternal { - AZ::Vector3 m_localPosition; ///< The starting position of the manipulator in local space. - AZ::Vector3 m_localHitPosition; ///< The intersection point in world space between the ray and the manipulator when the mouse down event happens. + AZ::Vector3 m_localPosition; //!< The starting position of the manipulator in local space. + AZ::Vector3 m_localHitPosition; //!< The intersection point in world space between the ray and the manipulator when the mouse + //!< down event happens. }; Fixed m_fixed; @@ -128,15 +140,23 @@ namespace AzToolsFramework MouseActionCallback m_onLeftMouseUpCallback = nullptr; MouseActionCallback m_onMouseMoveCallback = nullptr; - ManipulatorViews m_manipulatorViews; ///< Look of manipulator. + ManipulatorViews m_manipulatorViews; //!< Look of manipulator. static StartInternal CalculateManipulationDataStart( - const Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, - const AZ::Transform& localTransform, const ViewportInteraction::MouseInteraction& interaction, float intersectionDistance); + const Fixed& fixed, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& nonUniformScale, + const AZ::Transform& localTransform, + const ViewportInteraction::MouseInteraction& interaction, + float intersectionDistance); static Action CalculateManipulationDataAction( - const Fixed& fixed, const StartInternal& startInternal, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, - const AZ::Transform& localTransform, const GridSnapParameters& gridSnapParams, + const Fixed& fixed, + const StartInternal& startInternal, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& nonUniformScale, + const AZ::Transform& localTransform, + const GridSnapParameters& gridSnapParams, const ViewportInteraction::MouseInteraction& interaction); }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/RotationManipulators.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/RotationManipulators.cpp index 399bea4024..4bb39509e3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/RotationManipulators.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/RotationManipulators.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "RotationManipulators.h" @@ -28,8 +28,7 @@ namespace AzToolsFramework m_manipulatorSpaceWithLocalTransform.SetSpace(worldFromLocal); } - void RotationManipulators::InstallLeftMouseDownCallback( - const AngularManipulator::MouseActionCallback& onMouseDownCallback) + void RotationManipulators::InstallLeftMouseDownCallback(const AngularManipulator::MouseActionCallback& onMouseDownCallback) { for (AZStd::shared_ptr& manipulator : m_localAngularManipulators) { @@ -39,8 +38,7 @@ namespace AzToolsFramework m_viewAngularManipulator->InstallLeftMouseDownCallback(onMouseDownCallback); } - void RotationManipulators::InstallMouseMoveCallback( - const AngularManipulator::MouseActionCallback& onMouseMoveCallback) + void RotationManipulators::InstallMouseMoveCallback(const AngularManipulator::MouseActionCallback& onMouseMoveCallback) { for (AZStd::shared_ptr& manipulator : m_localAngularManipulators) { @@ -50,8 +48,7 @@ namespace AzToolsFramework m_viewAngularManipulator->InstallMouseMoveCallback(onMouseMoveCallback); } - void RotationManipulators::InstallLeftMouseUpCallback( - const AngularManipulator::MouseActionCallback& onMouseUpCallback) + void RotationManipulators::InstallLeftMouseUpCallback(const AngularManipulator::MouseActionCallback& onMouseUpCallback) { for (AZStd::shared_ptr& manipulator : m_localAngularManipulators) { @@ -109,14 +106,13 @@ namespace AzToolsFramework m_viewAngularManipulator->SetSpace(worldFromLocal); } - void RotationManipulators::SetLocalAxes( - const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3) + void RotationManipulators::SetLocalAxes(const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3) { const AZ::Vector3 axes[] = { axis1, axis2, axis3 }; for (size_t manipulatorIndex = 0; manipulatorIndex < m_localAngularManipulators.size(); ++manipulatorIndex) { - m_localAngularManipulators[manipulatorIndex]->SetAxis(axes[manipulatorIndex]); + m_localAngularManipulators[manipulatorIndex]->SetAxis(axes[manipulatorIndex]); } } @@ -124,34 +120,25 @@ namespace AzToolsFramework { m_viewAngularManipulator->SetAxis(axis); - if (auto circleView = azrtti_cast( - m_viewAngularManipulator->GetView())) + if (auto circleView = azrtti_cast(m_viewAngularManipulator->GetView())) { circleView->m_axis = axis; } } void RotationManipulators::ConfigureView( - const float radius, const AZ::Color& axis1Color, - const AZ::Color& axis2Color, const AZ::Color& axis3Color) + const float radius, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Color& axis3Color) { - const AZ::Color colors[] = { - axis1Color, axis2Color, axis3Color - }; + const AZ::Color colors[] = { axis1Color, axis2Color, axis3Color }; for (size_t manipulatorIndex = 0; manipulatorIndex < m_localAngularManipulators.size(); ++manipulatorIndex) { - m_localAngularManipulators[manipulatorIndex]->SetView( - CreateManipulatorViewCircle( - *m_localAngularManipulators[manipulatorIndex], colors[manipulatorIndex], - radius, 0.05f, DrawHalfDottedCircle)); + m_localAngularManipulators[manipulatorIndex]->SetView(CreateManipulatorViewCircle( + *m_localAngularManipulators[manipulatorIndex], colors[manipulatorIndex], radius, 0.05f, DrawHalfDottedCircle)); } - m_viewAngularManipulator->SetView( - CreateManipulatorViewCircle( - *m_viewAngularManipulator, - AZ::Color(1.0f, 1.0f, 1.0f, 1.0f), - radius + (radius * 0.12f), 0.05f, DrawFullCircle)); + m_viewAngularManipulator->SetView(CreateManipulatorViewCircle( + *m_viewAngularManipulator, AZ::Color(1.0f, 1.0f, 1.0f, 1.0f), radius + (radius * 0.12f), 0.05f, DrawFullCircle)); } bool RotationManipulators::PerformingActionViewAxis() const diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/RotationManipulators.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/RotationManipulators.h index 11b6e0838c..5ecfa21f26 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/RotationManipulators.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/RotationManipulators.h @@ -1,27 +1,26 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once #include -#include #include +#include namespace AzToolsFramework { - /// RotationManipulators is an aggregation of 3 angular manipulators who share the same origin - /// in addition to a view aligned angular manipulator (facing the camera). - class RotationManipulators - : public Manipulators + //! RotationManipulators is an aggregation of 3 angular manipulators who share the same origin + //! in addition to a view aligned angular manipulator (facing the camera). + class RotationManipulators : public Manipulators { public: AZ_RTTI(RotationManipulators, "{5D1F1D47-1D5B-4E42-B47E-23F108F8BF7D}") @@ -40,12 +39,10 @@ namespace AzToolsFramework void SetLocalOrientationImpl(const AZ::Quaternion& localOrientation) override; void RefreshView(const AZ::Vector3& worldViewPosition) override; - void SetLocalAxes( - const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3); + void SetLocalAxes(const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3); void SetViewAxis(const AZ::Vector3& axis); - void ConfigureView( - float radius, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Color& axis3Color); + void ConfigureView(float radius, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Color& axis3Color); bool PerformingActionViewAxis() const; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ScaleManipulators.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ScaleManipulators.cpp index caeedd834f..079fde669a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ScaleManipulators.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ScaleManipulators.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "ScaleManipulators.h" @@ -28,8 +28,7 @@ namespace AzToolsFramework m_manipulatorSpaceWithLocalTransform.SetSpace(worldFromLocal); } - void ScaleManipulators::InstallAxisLeftMouseDownCallback( - const LinearManipulator::MouseActionCallback& onMouseDownCallback) + void ScaleManipulators::InstallAxisLeftMouseDownCallback(const LinearManipulator::MouseActionCallback& onMouseDownCallback) { for (AZStd::shared_ptr& manipulator : m_axisScaleManipulators) { @@ -37,8 +36,7 @@ namespace AzToolsFramework } } - void ScaleManipulators::InstallAxisMouseMoveCallback( - const LinearManipulator::MouseActionCallback& onMouseMoveCallback) + void ScaleManipulators::InstallAxisMouseMoveCallback(const LinearManipulator::MouseActionCallback& onMouseMoveCallback) { for (AZStd::shared_ptr& manipulator : m_axisScaleManipulators) { @@ -46,8 +44,7 @@ namespace AzToolsFramework } } - void ScaleManipulators::InstallAxisLeftMouseUpCallback( - const LinearManipulator::MouseActionCallback& onMouseUpCallback) + void ScaleManipulators::InstallAxisLeftMouseUpCallback(const LinearManipulator::MouseActionCallback& onMouseUpCallback) { for (AZStd::shared_ptr& manipulator : m_axisScaleManipulators) { @@ -55,22 +52,19 @@ namespace AzToolsFramework } } - void ScaleManipulators::InstallUniformLeftMouseDownCallback( - const LinearManipulator::MouseActionCallback& onMouseDownCallback) + void ScaleManipulators::InstallUniformLeftMouseDownCallback(const LinearManipulator::MouseActionCallback& onMouseDownCallback) { m_uniformScaleManipulator->InstallLeftMouseDownCallback(onMouseDownCallback); } - void ScaleManipulators::InstallUniformMouseMoveCallback( - const LinearManipulator::MouseActionCallback& onMouseMoveCallback) + void ScaleManipulators::InstallUniformMouseMoveCallback(const LinearManipulator::MouseActionCallback& onMouseMoveCallback) { - m_uniformScaleManipulator->InstallMouseMoveCallback(onMouseMoveCallback); + m_uniformScaleManipulator->InstallMouseMoveCallback(onMouseMoveCallback); } - void ScaleManipulators::InstallUniformLeftMouseUpCallback( - const LinearManipulator::MouseActionCallback& onMouseUpCallback) + void ScaleManipulators::InstallUniformLeftMouseUpCallback(const LinearManipulator::MouseActionCallback& onMouseUpCallback) { - m_uniformScaleManipulator->InstallLeftMouseUpCallback(onMouseUpCallback); + m_uniformScaleManipulator->InstallLeftMouseUpCallback(onMouseUpCallback); } void ScaleManipulators::SetLocalTransformImpl(const AZ::Transform& localTransform) @@ -80,8 +74,7 @@ namespace AzToolsFramework manipulator->SetLocalTransform(localTransform); } - m_uniformScaleManipulator->SetVisualOrientationOverride( - QuaternionFromTransformNoScaling(localTransform)); + m_uniformScaleManipulator->SetVisualOrientationOverride(QuaternionFromTransformNoScaling(localTransform)); m_uniformScaleManipulator->SetLocalOrientation(AZ::Quaternion::CreateIdentity()); } @@ -113,14 +106,13 @@ namespace AzToolsFramework m_uniformScaleManipulator->SetSpace(worldFromLocal); } - void ScaleManipulators::SetAxes( - const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3) + void ScaleManipulators::SetAxes(const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3) { - AZ::Vector3 axes[] = { axis1, axis2, axis3 }; + AZ::Vector3 axes[] = { axis1, axis2, axis3 }; for (size_t manipulatorIndex = 0; manipulatorIndex < m_axisScaleManipulators.size(); ++manipulatorIndex) { - m_axisScaleManipulators[manipulatorIndex]->SetAxis(axes[manipulatorIndex]); + m_axisScaleManipulators[manipulatorIndex]->SetAxis(axes[manipulatorIndex]); } // uniform scale manipulator uses Z axis for scaling (always in world space) @@ -129,32 +121,27 @@ namespace AzToolsFramework } void ScaleManipulators::ConfigureView( - const float axisLength, const AZ::Color& axis1Color, - const AZ::Color& axis2Color, const AZ::Color& axis3Color) + const float axisLength, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Color& axis3Color) { const float boxSize = 0.1f; const float lineWidth = 0.05f; - const AZ::Color colors[] = { - axis1Color, axis2Color, axis3Color - }; + const AZ::Color colors[] = { axis1Color, axis2Color, axis3Color }; for (size_t manipulatorIndex = 0; manipulatorIndex < m_axisScaleManipulators.size(); ++manipulatorIndex) { ManipulatorViews views; - views.emplace_back(CreateManipulatorViewLine( - *m_axisScaleManipulators[manipulatorIndex], colors[manipulatorIndex], axisLength, lineWidth)); + views.emplace_back( + CreateManipulatorViewLine(*m_axisScaleManipulators[manipulatorIndex], colors[manipulatorIndex], axisLength, lineWidth)); views.emplace_back(CreateManipulatorViewBox( AZ::Transform::CreateIdentity(), colors[manipulatorIndex], - m_axisScaleManipulators[manipulatorIndex]->GetAxis() * (axisLength - boxSize), - AZ::Vector3(boxSize))); + m_axisScaleManipulators[manipulatorIndex]->GetAxis() * (axisLength - boxSize), AZ::Vector3(boxSize))); m_axisScaleManipulators[manipulatorIndex]->SetViews(AZStd::move(views)); } ManipulatorViews views; views.emplace_back(CreateManipulatorViewBox( - AZ::Transform::CreateIdentity(), AZ::Color::CreateOne(), - AZ::Vector3::CreateZero(), AZ::Vector3(boxSize))); + AZ::Transform::CreateIdentity(), AZ::Color::CreateOne(), AZ::Vector3::CreateZero(), AZ::Vector3(boxSize))); m_uniformScaleManipulator->SetViews(AZStd::move(views)); } @@ -167,4 +154,4 @@ namespace AzToolsFramework manipulatorFn(m_uniformScaleManipulator.get()); } -} +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ScaleManipulators.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ScaleManipulators.h index 24df3cda7b..b06d8f92c5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ScaleManipulators.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ScaleManipulators.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -17,11 +17,10 @@ namespace AzToolsFramework { - /// ScaleManipulators is an aggregation of 3 linear manipulators for each basis axis who share - /// the same transform, and a single linear manipulator at the center of the transform whose - /// axis is world up (z). - class ScaleManipulators - : public Manipulators + //! ScaleManipulators is an aggregation of 3 linear manipulators for each basis axis who share + //! the same transform, and a single linear manipulator at the center of the transform whose + //! axis is world up (z). + class ScaleManipulators : public Manipulators { public: AZ_RTTI(ScaleManipulators, "{C6350CE0-7B7A-46F8-B65F-D4A54DD9A7D9}") @@ -42,16 +41,9 @@ namespace AzToolsFramework void SetLocalPositionImpl(const AZ::Vector3& localPosition) override; void SetLocalOrientationImpl(const AZ::Quaternion& localOrientation) override; - void SetAxes( - const AZ::Vector3& axis1, - const AZ::Vector3& axis2, - const AZ::Vector3& axis3); + void SetAxes(const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3); - void ConfigureView( - float axisLength, - const AZ::Color& axis1Color, - const AZ::Color& axis2Color, - const AZ::Color& axis3Color); + void ConfigureView(float axisLength, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Color& axis3Color); private: AZ_DISABLE_COPY_MOVE(ScaleManipulators) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SelectionManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SelectionManipulator.cpp index 4925651580..3071ca74ae 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SelectionManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SelectionManipulator.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "SelectionManipulator.h" @@ -16,8 +16,8 @@ namespace AzToolsFramework { - AZStd::shared_ptr SelectionManipulator::MakeShared(const AZ::Transform& worldFromLocal, - const AZ::Vector3& nonUniformScale) + AZStd::shared_ptr SelectionManipulator::MakeShared( + const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale) { return AZStd::shared_ptr(aznew SelectionManipulator(worldFromLocal, nonUniformScale)); } @@ -93,12 +93,9 @@ namespace AzToolsFramework for (auto& view : m_manipulatorViews) { view->Draw( - GetManipulatorManagerId(), managerState, - GetManipulatorId(), { - TransformUniformScale(GetSpace()), GetNonUniformScale(), - GetLocalPosition(), MouseOver() - }, - debugDisplay, cameraState, mouseInteraction); + GetManipulatorManagerId(), managerState, GetManipulatorId(), + { TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay, cameraState, + mouseInteraction); } } @@ -117,4 +114,4 @@ namespace AzToolsFramework view->Invalidate(GetManipulatorManagerId()); } } -} +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SelectionManipulator.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SelectionManipulator.h index 1ae6ceb729..b862dfd684 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SelectionManipulator.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SelectionManipulator.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -20,13 +20,13 @@ namespace AzToolsFramework { class ManipulatorView; - /// Represents a sphere that can be clicked on to trigger a particular behavior - /// For example clicking a preview point to create a translation manipulator. + //! Represents a sphere that can be clicked on to trigger a particular behavior. + //! For example clicking a preview point to create a translation manipulator. class SelectionManipulator : public BaseManipulator , public ManipulatorSpaceWithLocalPosition { - /// Private constructor. + //! Private constructor. SelectionManipulator(const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale = AZ::Vector3::CreateOne()); public: @@ -39,12 +39,12 @@ namespace AzToolsFramework ~SelectionManipulator() = default; - /// A Manipulator must only be created and managed through a shared_ptr. - static AZStd::shared_ptr MakeShared(const AZ::Transform& worldFromLocal, - const AZ::Vector3& nonUniformScale = AZ::Vector3::CreateOne()); + //! A Manipulator must only be created and managed through a shared_ptr. + static AZStd::shared_ptr MakeShared( + const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale = AZ::Vector3::CreateOne()); - /// This is the function signature of callbacks that will be invoked - /// whenever a selection manipulator is clicked on. + //! This is the function signature of callbacks that will be invoked + //! whenever a selection manipulator is clicked on. using MouseActionCallback = AZStd::function; void InstallLeftMouseDownCallback(const MouseActionCallback& onMouseDownCallback); @@ -58,10 +58,25 @@ namespace AzToolsFramework const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) override; - bool Selected() const { return m_selected; } - void Select() { m_selected = true; } - void Deselect() { m_selected = false; } - void ToggleSelected() { m_selected = !m_selected; } + bool Selected() const + { + return m_selected; + } + + void Select() + { + m_selected = true; + } + + void Deselect() + { + m_selected = false; + } + + void ToggleSelected() + { + m_selected = !m_selected; + } template void SetViews(Views&& views) @@ -70,13 +85,9 @@ namespace AzToolsFramework } private: - void OnLeftMouseDownImpl( - const ViewportInteraction::MouseInteraction& interaction, - float rayIntersectionDistance) override; + void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override; - void OnRightMouseDownImpl( - const ViewportInteraction::MouseInteraction& interaction, - float rayIntersectionDistance) override; + void OnRightMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; void OnRightMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override; void InvalidateImpl() override; @@ -89,6 +100,6 @@ namespace AzToolsFramework MouseActionCallback m_onRightMouseDownCallback = nullptr; MouseActionCallback m_onRightMouseUpCallback = nullptr; - ManipulatorViews m_manipulatorViews; ///< Look of manipulator. + ManipulatorViews m_manipulatorViews; //!< Look of manipulator. }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineHoverSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineHoverSelection.cpp index 43fbbce80b..98972bcf33 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineHoverSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineHoverSelection.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "SplineHoverSelection.h" @@ -20,11 +20,12 @@ namespace AzToolsFramework { - static const AZ::Color s_splineSelectManipulatorColor = AZ::Color(0.0f, 1.0f, 0.0f, 1.0f); + static const AZ::Color SplineSelectManipulatorColor = AZ::Color(0.0f, 1.0f, 0.0f, 1.0f); SplineHoverSelection::SplineHoverSelection( const AZ::EntityComponentIdPair& entityComponentIdPair, - const ManipulatorManagerId managerId, const AZStd::shared_ptr& spline) + const ManipulatorManagerId managerId, + const AZStd::shared_ptr& spline) { m_splineSelectionManipulator = SplineSelectionManipulator::MakeShared(); m_splineSelectionManipulator->Register(managerId); @@ -33,16 +34,14 @@ namespace AzToolsFramework const float splineWidth = 0.05f; m_splineSelectionManipulator->SetSpline(spline); - m_splineSelectionManipulator->SetView(CreateManipulatorViewSplineSelect( - *m_splineSelectionManipulator, s_splineSelectManipulatorColor, splineWidth)); + m_splineSelectionManipulator->SetView( + CreateManipulatorViewSplineSelect(*m_splineSelectionManipulator, SplineSelectManipulatorColor, splineWidth)); m_splineSelectionManipulator->InstallLeftMouseUpCallback( [entityComponentIdPair](const SplineSelectionManipulator::Action& action) - { - InsertVertexAfter( - entityComponentIdPair, action.m_splineAddress.m_segmentIndex, - action.m_localSplineHitPosition); - }); + { + InsertVertexAfter(entityComponentIdPair, action.m_splineAddress.m_segmentIndex, action.m_localSplineHitPosition); + }); } SplineHoverSelection::~SplineHoverSelection() diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineHoverSelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineHoverSelection.h index 11b10f8516..d8dcd573af 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineHoverSelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineHoverSelection.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -19,20 +19,20 @@ namespace AZ { class Spline; class EntityComponentIdPair; -} +} // namespace AZ namespace AzToolsFramework { class SplineSelectionManipulator; - /// SplineHoverSelection is a concrete implementation of HoverSelection wrapping a Spline and - /// SplineManipulator. The underlying manipulators are used to control selection. - class SplineHoverSelection - : public HoverSelection + //! SplineHoverSelection is a concrete implementation of HoverSelection wrapping a Spline and + //! SplineManipulator. The underlying manipulators are used to control selection. + class SplineHoverSelection : public HoverSelection { public: explicit SplineHoverSelection( - const AZ::EntityComponentIdPair& entityComponentIdPair, ManipulatorManagerId managerId, + const AZ::EntityComponentIdPair& entityComponentIdPair, + ManipulatorManagerId managerId, const AZStd::shared_ptr& spline); SplineHoverSelection(const SplineHoverSelection&) = delete; SplineHoverSelection& operator=(const SplineHoverSelection&) = delete; @@ -46,6 +46,6 @@ namespace AzToolsFramework void SetNonUniformScale(const AZ::Vector3& nonUniformScale) override; private: - AZStd::shared_ptr m_splineSelectionManipulator; ///< Manipulator for adding points to spline. + AZStd::shared_ptr m_splineSelectionManipulator; //!< Manipulator for adding points to spline. }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineSelectionManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineSelectionManipulator.cpp index 5bfccefe48..39dbcb67fa 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineSelectionManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineSelectionManipulator.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "SplineSelectionManipulator.h" @@ -18,8 +18,10 @@ namespace AzToolsFramework { SplineSelectionManipulator::Action CalculateManipulationDataAction( - const AZ::Transform& worldFromLocal, const AZ::Vector3& rayOrigin, - const AZ::Vector3& rayDirection, const AZStd::weak_ptr& spline) + const AZ::Transform& worldFromLocal, + const AZ::Vector3& rayOrigin, + const AZ::Vector3& rayDirection, + const AZStd::weak_ptr& spline) { SplineSelectionManipulator::Action action; if (const AZStd::shared_ptr splinePtr = spline.lock()) @@ -65,9 +67,7 @@ namespace AzToolsFramework if (m_onLeftMouseDownCallback) { m_onLeftMouseDownCallback(CalculateManipulationDataAction( - TransformUniformScale(GetSpace()), - interaction.m_mousePick.m_rayOrigin, - interaction.m_mousePick.m_rayDirection, m_spline)); + TransformUniformScale(GetSpace()), interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, m_spline)); } } @@ -76,9 +76,7 @@ namespace AzToolsFramework if (MouseOver() && m_onLeftMouseUpCallback) { m_onLeftMouseUpCallback(CalculateManipulationDataAction( - TransformUniformScale(GetSpace()), - interaction.m_mousePick.m_rayOrigin, - interaction.m_mousePick.m_rayDirection, m_spline)); + TransformUniformScale(GetSpace()), interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, m_spline)); } } @@ -99,12 +97,9 @@ namespace AzToolsFramework if (mouseInteraction.m_keyboardModifiers.Ctrl() && !mouseInteraction.m_keyboardModifiers.Shift()) { m_manipulatorView->Draw( - GetManipulatorManagerId(), managerState, - GetManipulatorId(), { - TransformUniformScale(GetSpace()), GetNonUniformScale(), - AZ::Vector3::CreateZero(), MouseOver() - }, - debugDisplay, cameraState, mouseInteraction); + GetManipulatorManagerId(), managerState, GetManipulatorId(), + { TransformUniformScale(GetSpace()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, + cameraState, mouseInteraction); } } @@ -122,4 +117,4 @@ namespace AzToolsFramework { m_manipulatorView->Invalidate(GetManipulatorManagerId()); } -} +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineSelectionManipulator.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineSelectionManipulator.h index 721c3413ef..e1a2fe26ab 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineSelectionManipulator.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineSelectionManipulator.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -23,13 +23,13 @@ namespace AzToolsFramework { class ManipulatorView; - /// A manipulator to represent selection of a spline. Underlying spline data is - /// used to test mouse picking ray against to preview closest point on spline. + //! A manipulator to represent selection of a spline. Underlying spline data is + //! used to test mouse picking ray against to preview closest point on spline. class SplineSelectionManipulator : public BaseManipulator , public ManipulatorSpace { - /// Private constructor. + //! Private constructor. SplineSelectionManipulator(); public: @@ -41,10 +41,10 @@ namespace AzToolsFramework ~SplineSelectionManipulator(); - /// A Manipulator must only be created and managed through a shared_ptr. + //! A Manipulator must only be created and managed through a shared_ptr. static AZStd::shared_ptr MakeShared(); - /// Mouse action data used by MouseActionCallback. + //! Mouse action data used by MouseActionCallback. struct Action { AZ::Vector3 m_localSplineHitPosition; @@ -62,29 +62,36 @@ namespace AzToolsFramework const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteraction& mouseInteraction) override; - void SetSpline(AZStd::shared_ptr spline) { m_spline = AZStd::move(spline); } - AZStd::weak_ptr GetSpline() const { return m_spline; } + void SetSpline(AZStd::shared_ptr spline) + { + m_spline = AZStd::move(spline); + } + AZStd::weak_ptr GetSpline() const + { + return m_spline; + } void SetView(AZStd::unique_ptr&& view); private: - void OnLeftMouseDownImpl( - const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; - void OnLeftMouseUpImpl( - const ViewportInteraction::MouseInteraction& interaction) override; + void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; + void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override; void InvalidateImpl() override; void SetBoundsDirtyImpl() override; AZStd::weak_ptr m_spline; - AZStd::unique_ptr m_manipulatorView = nullptr; ///< Look of manipulator and bounds for interaction. + AZStd::unique_ptr m_manipulatorView = nullptr; //!< Look of manipulator and bounds for interaction. MouseActionCallback m_onLeftMouseDownCallback = nullptr; MouseActionCallback m_onLeftMouseUpCallback = nullptr; - ViewportInteraction::KeyboardModifiers m_keyboardModifiers; ///< What modifier keys are pressed when interacting with this manipulator. + ViewportInteraction::KeyboardModifiers + m_keyboardModifiers; //!< What modifier keys are pressed when interacting with this manipulator. }; SplineSelectionManipulator::Action CalculateManipulationDataAction( - const AZ::Transform& worldFromLocal, const AZ::Vector3& rayOrigin, - const AZ::Vector3& rayDirection, const AZStd::weak_ptr& spline); + const AZ::Transform& worldFromLocal, + const AZ::Vector3& rayOrigin, + const AZ::Vector3& rayDirection, + const AZStd::weak_ptr& spline); } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp index f570c20a7e..aa3f3f5882 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "SurfaceManipulator.h" @@ -18,19 +18,22 @@ namespace AzToolsFramework { SurfaceManipulator::StartInternal SurfaceManipulator::CalculateManipulationDataStart( - const AZ::Transform& worldFromLocal, const AZ::Vector3& worldSurfacePosition, - const AZ::Vector3& localStartPosition, const bool snapping, const float gridSize, const int viewportId) + const AZ::Transform& worldFromLocal, + const AZ::Vector3& worldSurfacePosition, + const AZ::Vector3& localStartPosition, + const bool snapping, + const float gridSize, + const int viewportId) { const AZ::Transform worldFromLocalUniform = AzToolsFramework::TransformUniformScale(worldFromLocal); const AZ::Transform localFromWorldUniform = worldFromLocalUniform.GetInverse(); const AZ::Vector3 localFinalSurfacePosition = snapping - ? CalculateSnappedTerrainPosition( - // note: gridSize is not scaled by scaleRecip here as localStartPosition is - // unscaled itself so the position returned by CalculateSnappedTerrainPosition - // must be in the same space (if localStartPosition were also scaled, gridSize - // would need to be multiplied by scaleRecip) - worldSurfacePosition, worldFromLocalUniform, viewportId, gridSize) + // note: gridSize is not scaled by scaleRecip here as localStartPosition is + // unscaled itself so the position returned by CalculateSnappedTerrainPosition + // must be in the same space (if localStartPosition were also scaled, gridSize + // would need to be multiplied by scaleRecip) + ? CalculateSnappedTerrainPosition(worldSurfacePosition, worldFromLocalUniform, viewportId, gridSize) : localFromWorldUniform.TransformPoint(worldSurfacePosition); // delta/offset between initial vertex position and terrain pick position @@ -44,9 +47,13 @@ namespace AzToolsFramework } SurfaceManipulator::Action SurfaceManipulator::CalculateManipulationDataAction( - const StartInternal& startInternal, const AZ::Transform& worldFromLocal, - const AZ::Vector3& worldSurfacePosition, const bool snapping, const float gridSize, - const ViewportInteraction::KeyboardModifiers keyboardModifiers, const int viewportId) + const StartInternal& startInternal, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& worldSurfacePosition, + const bool snapping, + const float gridSize, + const ViewportInteraction::KeyboardModifiers keyboardModifiers, + const int viewportId) { const AZ::Transform worldFromLocalUniform = AzToolsFramework::TransformUniformScale(worldFromLocal); const AZ::Transform localFromWorldUniform = worldFromLocalUniform.GetInverse(); @@ -54,8 +61,7 @@ namespace AzToolsFramework const float scaleRecip = ScaleReciprocal(worldFromLocalUniform); const AZ::Vector3 localFinalSurfacePosition = snapping - ? CalculateSnappedTerrainPosition( - worldSurfacePosition, worldFromLocalUniform, viewportId, gridSize * scaleRecip) + ? CalculateSnappedTerrainPosition(worldSurfacePosition, worldFromLocalUniform, viewportId, gridSize * scaleRecip) : localFromWorldUniform.TransformPoint(worldSurfacePosition); Action action; @@ -106,17 +112,14 @@ namespace AzToolsFramework interaction.m_mousePick.m_screenCoordinates); m_startInternal = CalculateManipulationDataStart( - worldFromLocalUniformScale, worldSurfacePosition, GetLocalPosition(), - gridSnapParams.m_gridSnap, gridSnapParams.m_gridSize, + worldFromLocalUniformScale, worldSurfacePosition, GetLocalPosition(), gridSnapParams.m_gridSnap, gridSnapParams.m_gridSize, interaction.m_interactionId.m_viewportId); if (m_onLeftMouseDownCallback) { m_onLeftMouseDownCallback(CalculateManipulationDataAction( - m_startInternal, worldFromLocalUniformScale, worldSurfacePosition, - gridSnapParams.m_gridSnap, gridSnapParams.m_gridSize, - interaction.m_keyboardModifiers, - interaction.m_interactionId.m_viewportId)); + m_startInternal, worldFromLocalUniformScale, worldSurfacePosition, gridSnapParams.m_gridSnap, gridSnapParams.m_gridSize, + interaction.m_keyboardModifiers, interaction.m_interactionId.m_viewportId)); } } @@ -133,10 +136,8 @@ namespace AzToolsFramework const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId); m_onLeftMouseUpCallback(CalculateManipulationDataAction( - m_startInternal, TransformUniformScale(GetSpace()), worldSurfacePosition, - gridSnapParams.m_gridSnap, - gridSnapParams.m_gridSize, - interaction.m_keyboardModifiers, interaction.m_interactionId.m_viewportId)); + m_startInternal, TransformUniformScale(GetSpace()), worldSurfacePosition, gridSnapParams.m_gridSnap, + gridSnapParams.m_gridSize, interaction.m_keyboardModifiers, interaction.m_interactionId.m_viewportId)); } } @@ -153,10 +154,8 @@ namespace AzToolsFramework const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId); m_onMouseMoveCallback(CalculateManipulationDataAction( - m_startInternal, TransformUniformScale(GetSpace()), worldSurfacePosition, - gridSnapParams.m_gridSnap, - gridSnapParams.m_gridSize, - interaction.m_keyboardModifiers, interaction.m_interactionId.m_viewportId)); + m_startInternal, TransformUniformScale(GetSpace()), worldSurfacePosition, gridSnapParams.m_gridSnap, + gridSnapParams.m_gridSize, interaction.m_keyboardModifiers, interaction.m_interactionId.m_viewportId)); } } @@ -172,12 +171,9 @@ namespace AzToolsFramework const ViewportInteraction::MouseInteraction& mouseInteraction) { m_manipulatorView->Draw( - GetManipulatorManagerId(), managerState, - GetManipulatorId(), { - TransformUniformScale(GetSpace()), GetNonUniformScale(), - GetLocalPosition(), MouseOver() - }, - debugDisplay, cameraState, mouseInteraction); + GetManipulatorManagerId(), managerState, GetManipulatorId(), + { TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay, cameraState, + mouseInteraction); } void SurfaceManipulator::InvalidateImpl() @@ -189,4 +185,4 @@ namespace AzToolsFramework { m_manipulatorView = AZStd::move(view); } -} +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.h index 72eb3a5cda..6461954353 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -21,13 +21,13 @@ namespace AzToolsFramework { class ManipulatorView; - /// Surface manipulator will ensure the point(s) it controls snap precisely to the xy grid - /// while also staying aligned exactly to the height of the terrain. + //! Surface manipulator will ensure the point(s) it controls snap precisely to the xy grid + //! while also staying aligned exactly to the height of the terrain. class SurfaceManipulator : public BaseManipulator , public ManipulatorSpaceWithLocalPosition { - /// Private constructor. + //! Private constructor. explicit SurfaceManipulator(const AZ::Transform& worldFromLocal); public: @@ -40,30 +40,36 @@ namespace AzToolsFramework ~SurfaceManipulator() = default; - /// A Manipulator must only be created and managed through a shared_ptr. + //! A Manipulator must only be created and managed through a shared_ptr. static AZStd::shared_ptr MakeShared(const AZ::Transform& worldFromLocal); - /// The state of the manipulator at the start of an interaction. + //! The state of the manipulator at the start of an interaction. struct Start { - AZ::Vector3 m_localPosition; ///< The current position of the manipulator in local space. - AZ::Vector3 m_snapOffset; ///< The snap offset amount to ensure manipulator is aligned to the grid. + AZ::Vector3 m_localPosition; //!< The current position of the manipulator in local space. + AZ::Vector3 m_snapOffset; //!< The snap offset amount to ensure manipulator is aligned to the grid. }; - /// The state of the manipulator during an interaction. + //! The state of the manipulator during an interaction. struct Current { - AZ::Vector3 m_localOffset; ///< The current offset of the manipulator from its starting position in local space. + AZ::Vector3 m_localOffset; //!< The current offset of the manipulator from its starting position in local space. }; - /// Mouse action data used by MouseActionCallback (wraps Start and Current manipulator state). + //! Mouse action data used by MouseActionCallback (wraps Start and Current manipulator state). struct Action { Start m_start; Current m_current; ViewportInteraction::KeyboardModifiers m_modifiers; - AZ::Vector3 LocalPosition() const { return m_start.m_localPosition + m_current.m_localOffset; } - AZ::Vector3 LocalPositionOffset() const { return m_current.m_localOffset; } + AZ::Vector3 LocalPosition() const + { + return m_start.m_localPosition + m_current.m_localOffset; + } + AZ::Vector3 LocalPositionOffset() const + { + return m_current.m_localOffset; + } }; using MouseActionCallback = AZStd::function; @@ -81,39 +87,44 @@ namespace AzToolsFramework void SetView(AZStd::unique_ptr&& view); private: - void OnLeftMouseDownImpl( - const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; - void OnLeftMouseUpImpl( - const ViewportInteraction::MouseInteraction& interaction) override; - void OnMouseMoveImpl( - const ViewportInteraction::MouseInteraction& interaction) override; + void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override; + void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override; + void OnMouseMoveImpl(const ViewportInteraction::MouseInteraction& interaction) override; void InvalidateImpl() override; void SetBoundsDirtyImpl() override; - /// Initial data recorded when a press first happens with a surface manipulator. + //! Initial data recorded when a press first happens with a surface manipulator. struct StartInternal { - AZ::Vector3 m_localPosition; ///< The current position of the manipulator in local space. - AZ::Vector3 m_localHitPosition; ///< The hit position with the terrain in local space. - AZ::Vector3 m_snapOffset; ///< The snap offset amount to ensure manipulator is aligned to the grid. + AZ::Vector3 m_localPosition; //!< The current position of the manipulator in local space. + AZ::Vector3 m_localHitPosition; //!< The hit position with the terrain in local space. + AZ::Vector3 m_snapOffset; //!< The snap offset amount to ensure manipulator is aligned to the grid. }; - StartInternal m_startInternal; ///< Internal initial state recorded/created in OnMouseDown. + StartInternal m_startInternal; //!< Internal initial state recorded/created in OnMouseDown. - AZStd::unique_ptr m_manipulatorView = nullptr; ///< Look of manipulator. + AZStd::unique_ptr m_manipulatorView = nullptr; //!< Look of manipulator. MouseActionCallback m_onLeftMouseDownCallback = nullptr; MouseActionCallback m_onLeftMouseUpCallback = nullptr; MouseActionCallback m_onMouseMoveCallback = nullptr; static StartInternal CalculateManipulationDataStart( - const AZ::Transform& worldFromLocal, const AZ::Vector3& worldSurfacePosition, - const AZ::Vector3& localPosition, bool snapping, float gridSize, int viewportId); + const AZ::Transform& worldFromLocal, + const AZ::Vector3& worldSurfacePosition, + const AZ::Vector3& localPosition, + bool snapping, + float gridSize, + int viewportId); static Action CalculateManipulationDataAction( - const StartInternal& startInternal, const AZ::Transform& worldFromLocal, - const AZ::Vector3& worldSurfacePosition, bool snapping, float gridSize, - ViewportInteraction::KeyboardModifiers keyboardModifiers, int viewportId); + const StartInternal& startInternal, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& worldSurfacePosition, + bool snapping, + float gridSize, + ViewportInteraction::KeyboardModifiers keyboardModifiers, + int viewportId); }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.cpp index bfdfd8ba08..57d175c34e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "TranslationManipulators.h" @@ -77,8 +77,7 @@ namespace AzToolsFramework } } - void TranslationManipulators::InstallLinearManipulatorMouseUpCallback( - const LinearManipulator::MouseActionCallback& onMouseUpCallback) + void TranslationManipulators::InstallLinearManipulatorMouseUpCallback(const LinearManipulator::MouseActionCallback& onMouseUpCallback) { for (AZStd::shared_ptr& manipulator : m_linearManipulators) { @@ -104,8 +103,7 @@ namespace AzToolsFramework } } - void TranslationManipulators::InstallPlanarManipulatorMouseUpCallback( - const PlanarManipulator::MouseActionCallback& onMouseUpCallback) + void TranslationManipulators::InstallPlanarManipulatorMouseUpCallback(const PlanarManipulator::MouseActionCallback& onMouseUpCallback) { for (AZStd::shared_ptr& manipulator : m_planarManipulators) { @@ -122,8 +120,7 @@ namespace AzToolsFramework } } - void TranslationManipulators::InstallSurfaceManipulatorMouseUpCallback( - const SurfaceManipulator::MouseActionCallback& onMouseUpCallback) + void TranslationManipulators::InstallSurfaceManipulatorMouseUpCallback(const SurfaceManipulator::MouseActionCallback& onMouseUpCallback) { if (m_surfaceManipulator) { @@ -242,7 +239,9 @@ namespace AzToolsFramework } void TranslationManipulators::ConfigureLinearView( - float axisLength, const AZ::Color& axis1Color, const AZ::Color& axis2Color, + float axisLength, + const AZ::Color& axis1Color, + const AZ::Color& axis2Color, const AZ::Color& axis3Color /*= AZ::Color(0.0f, 0.0f, 1.0f, 0.5f)*/) { const float coneLength = 0.28f; @@ -251,15 +250,13 @@ namespace AzToolsFramework const AZ::Color axesColor[] = { axis1Color, axis2Color, axis3Color }; - const auto configureLinearView = [lineWidth, coneLength, axisLength, coneRadius]( - LinearManipulator* linearManipulator, const AZ::Color& color) + const auto configureLinearView = + [lineWidth, coneLength, axisLength, coneRadius](LinearManipulator* linearManipulator, const AZ::Color& color) { ManipulatorViews views; - views.emplace_back(CreateManipulatorViewLine( - *linearManipulator, color, axisLength, lineWidth)); + views.emplace_back(CreateManipulatorViewLine(*linearManipulator, color, axisLength, lineWidth)); views.emplace_back(CreateManipulatorViewCone( - *linearManipulator, color, linearManipulator->GetAxis() * (axisLength - coneLength), - coneLength, coneRadius)); + *linearManipulator, color, linearManipulator->GetAxis() * (axisLength - coneLength), coneLength, coneRadius)); linearManipulator->SetViews(AZStd::move(views)); }; @@ -270,7 +267,8 @@ namespace AzToolsFramework } void TranslationManipulators::ConfigurePlanarView( - const AZ::Color& plane1Color, const AZ::Color& plane2Color /*= AZ::Color(0.0f, 1.0f, 0.0f, 0.5f)*/, + const AZ::Color& plane1Color, + const AZ::Color& plane2Color /*= AZ::Color(0.0f, 1.0f, 0.0f, 0.5f)*/, const AZ::Color& plane3Color /*= AZ::Color(0.0f, 0.0f, 1.0f, 0.5f)*/) { const float planeSize = 0.6f; @@ -278,34 +276,29 @@ namespace AzToolsFramework for (size_t manipulatorIndex = 0; manipulatorIndex < m_planarManipulators.size(); ++manipulatorIndex) { - const AZStd::shared_ptr manipulatorView = - CreateManipulatorViewQuad( - *m_planarManipulators[manipulatorIndex], planesColor[manipulatorIndex], - planesColor[(manipulatorIndex + 1) % 3], - planeSize); + const AZStd::shared_ptr manipulatorView = CreateManipulatorViewQuad( + *m_planarManipulators[manipulatorIndex], planesColor[manipulatorIndex], planesColor[(manipulatorIndex + 1) % 3], planeSize); - m_planarManipulators[manipulatorIndex]->SetViews(ManipulatorViews{manipulatorView}); + m_planarManipulators[manipulatorIndex]->SetViews(ManipulatorViews{ manipulatorView }); } } - void TranslationManipulators::ConfigureSurfaceView( - const float radius, const AZ::Color& color) + void TranslationManipulators::ConfigureSurfaceView(const float radius, const AZ::Color& color) { if (m_surfaceManipulator) { - m_surfaceManipulator->SetView(CreateManipulatorViewSphere(color, radius, - [](const ViewportInteraction::MouseInteraction& /*mouseInteraction*/, - bool mouseOver, const AZ::Color& defaultColor) -> AZ::Color - { - const AZ::Color color[2] = + m_surfaceManipulator->SetView(CreateManipulatorViewSphere( + color, radius, + [](const ViewportInteraction::MouseInteraction& /*mouseInteraction*/, bool mouseOver, + const AZ::Color& defaultColor) -> AZ::Color { - defaultColor, - Vector3ToVector4( - BaseManipulator::s_defaultMouseOverColor.GetAsVector3(), s_surfaceManipulatorTransparency) - }; + const AZ::Color color[2] = { + defaultColor, + Vector3ToVector4(BaseManipulator::s_defaultMouseOverColor.GetAsVector3(), s_surfaceManipulatorTransparency) + }; - return color[mouseOver]; - })); + return color[mouseOver]; + })); } } @@ -327,27 +320,17 @@ namespace AzToolsFramework } } - void ConfigureTranslationManipulatorAppearance3d( - TranslationManipulators* translationManipulators) + void ConfigureTranslationManipulatorAppearance3d(TranslationManipulators* translationManipulators) { - translationManipulators->SetAxes( - AZ::Vector3::CreateAxisX(), - AZ::Vector3::CreateAxisY(), - AZ::Vector3::CreateAxisZ()); - translationManipulators->ConfigurePlanarView( - s_xAxisColor, s_yAxisColor, s_zAxisColor); - translationManipulators->ConfigureLinearView( - s_axisLength, s_xAxisColor, s_yAxisColor, s_zAxisColor); - translationManipulators->ConfigureSurfaceView( - s_surfaceManipulatorRadius, s_surfaceManipulatorColor); + translationManipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ()); + translationManipulators->ConfigurePlanarView(s_xAxisColor, s_yAxisColor, s_zAxisColor); + translationManipulators->ConfigureLinearView(s_axisLength, s_xAxisColor, s_yAxisColor, s_zAxisColor); + translationManipulators->ConfigureSurfaceView(s_surfaceManipulatorRadius, s_surfaceManipulatorColor); } - void ConfigureTranslationManipulatorAppearance2d( - TranslationManipulators* translationManipulators) + void ConfigureTranslationManipulatorAppearance2d(TranslationManipulators* translationManipulators) { - translationManipulators->SetAxes( - AZ::Vector3::CreateAxisX(), - AZ::Vector3::CreateAxisY()); + translationManipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY()); translationManipulators->ConfigurePlanarView(s_xAxisColor); translationManipulators->ConfigureLinearView(s_axisLength, s_xAxisColor, s_yAxisColor); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.h index 0e7d3108aa..5f5f1a71e3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -19,16 +19,15 @@ namespace AzToolsFramework { - /// TranslationManipulators is an aggregation of 3 linear manipulators, 3 planar manipulators - /// and one surface manipulator who share the same transform. - class TranslationManipulators - : public Manipulators + //! TranslationManipulators is an aggregation of 3 linear manipulators, 3 planar manipulators + //! and one surface manipulator who share the same transform. + class TranslationManipulators : public Manipulators { public: AZ_RTTI(TranslationManipulators, "{D5E49EA2-30E0-42BC-A51D-6A7F87818260}") AZ_CLASS_ALLOCATOR(TranslationManipulators, AZ::SystemAllocator, 0) - /// How many dimensions does this translation manipulator have + //! How many dimensions does this translation manipulator have. enum class Dimensions { Two, @@ -55,9 +54,7 @@ namespace AzToolsFramework void SetLocalOrientationImpl(const AZ::Quaternion& localOrientation) override; void SetNonUniformScaleImpl(const AZ::Vector3& nonUniformScale) override; - void SetAxes( - const AZ::Vector3& axis1, const AZ::Vector3& axis2, - const AZ::Vector3& axis3 = AZ::Vector3::CreateAxisZ()); + void SetAxes(const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3 = AZ::Vector3::CreateAxisZ()); void ConfigurePlanarView( const AZ::Color& plane1Color, @@ -66,11 +63,11 @@ namespace AzToolsFramework void ConfigureLinearView( float axisLength, - const AZ::Color& axis1Color, const AZ::Color& axis2Color, + const AZ::Color& axis1Color, + const AZ::Color& axis2Color, const AZ::Color& axis3Color = AZ::Color(0.0f, 0.0f, 1.0f, 0.5f)); - void ConfigureSurfaceView( - float radius, const AZ::Color& color); + void ConfigureSurfaceView(float radius, const AZ::Color& color); private: AZ_DISABLE_COPY_MOVE(TranslationManipulators) @@ -78,37 +75,43 @@ namespace AzToolsFramework // Manipulators void ProcessManipulators(const AZStd::function&) override; - const Dimensions m_dimensions; ///< How many dimensions of freedom does this manipulator have. + const Dimensions m_dimensions; //!< How many dimensions of freedom does this manipulator have. AZStd::vector> m_linearManipulators; AZStd::vector> m_planarManipulators; AZStd::shared_ptr m_surfaceManipulator = nullptr; }; - /// IndexedTranslationManipulator wraps a standard TranslationManipulators and allows it to be linked - /// to a particular index in a list of vertices/points. + //! IndexedTranslationManipulator wraps a standard TranslationManipulators and allows it to be linked + //! to a particular index in a list of vertices/points. template struct IndexedTranslationManipulator { explicit IndexedTranslationManipulator( - TranslationManipulators::Dimensions dimensions, AZ::u64 vertIndex, - const Vertex& position, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale) - : m_manipulator(dimensions, worldFromLocal, nonUniformScale) + TranslationManipulators::Dimensions dimensions, + AZ::u64 vertIndex, + const Vertex& position, + const AZ::Transform& worldFromLocal, + const AZ::Vector3& nonUniformScale) + : m_manipulator(dimensions, worldFromLocal, nonUniformScale) { m_vertices.push_back({ position, Vertex::CreateZero(), vertIndex }); } - /// Store vertex start position as manipulator event occurs, index refers to location in container. + //! Store vertex start position as manipulator event occurs, index refers to location in container. struct VertexLookup { Vertex m_start; Vertex m_offset; AZ::u64 m_index; - Vertex CurrentPosition() const { return m_start + m_offset; } + Vertex CurrentPosition() const + { + return m_start + m_offset; + } }; - /// Helper to iterate over all vertices stored by the manipulator. + //! Helper to iterate over all vertices stored by the manipulator. void Process(AZStd::function fn) { for (VertexLookup& vertex : m_vertices) @@ -117,16 +120,14 @@ namespace AzToolsFramework } } - AZStd::vector m_vertices; ///< List of vertices currently associated with this translation manipulator. + AZStd::vector m_vertices; //!< List of vertices currently associated with this translation manipulator. TranslationManipulators m_manipulator; }; - /// Function pointer to configure how a translation manipulator should look and behave (dimensions/axes/views). - using TranslationManipulatorConfiguratorFn = void(*)(TranslationManipulators*); + //! Function pointer to configure how a translation manipulator should look and behave (dimensions/axes/views). + using TranslationManipulatorConfiguratorFn = void (*)(TranslationManipulators*); - void ConfigureTranslationManipulatorAppearance3d( - TranslationManipulators* translationManipulators); - void ConfigureTranslationManipulatorAppearance2d( - TranslationManipulators* translationManipulators); + void ConfigureTranslationManipulatorAppearance3d(TranslationManipulators* translationManipulators); + void ConfigureTranslationManipulatorAppearance2d(TranslationManipulators* translationManipulators); } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/BoundInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/BoundInterface.h index 3b579e889e..e8e822ca32 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/BoundInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/BoundInterface.h @@ -1,14 +1,15 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + #pragma once #include @@ -16,30 +17,44 @@ namespace AzToolsFramework { - /** - * Provide unique type alias for AZ::u64 for manipulator, bounds and manager. - */ + //! Provide unique type alias for AZ::u64 for manipulator, bounds and manager. template class IdType { public: explicit IdType(AZ::u64 id = 0) - : m_id(id) {} - operator AZ::u64() const { return m_id; } + : m_id(id) + { + } + + operator AZ::u64() const + { + return m_id; + } + + bool operator==(IdType other) const + { + return m_id == other.m_id; + } + + bool operator!=(IdType other) const + { + return m_id != other.m_id; + } - bool operator==(IdType other) const { return m_id == other.m_id; } - bool operator!=(IdType other) const { return m_id != other.m_id; } IdType& operator++() // pre-increment { ++m_id; return *this; } + IdType operator++(int) // post-increment { IdType temp = *this; ++*this; return temp; } + private: AZ::u64 m_id; }; @@ -51,10 +66,8 @@ namespace AzToolsFramework using RegisteredBoundId = IdType; static const RegisteredBoundId InvalidBoundId = RegisteredBoundId(0); - /** - * This class serves as the base class for the actual bound shapes that various DefaultContextBoundManager-derived - * classes return from the function CreateShape. - */ + //! This class serves as the base class for the actual bound shapes that various DefaultContextBoundManager-derived + //! classes return from the function CreateShape. class BoundShapeInterface { public: @@ -63,25 +76,33 @@ namespace AzToolsFramework explicit BoundShapeInterface(const RegisteredBoundId boundId) : m_boundId(boundId) , m_valid(false) - {} + { + } virtual ~BoundShapeInterface() = default; - RegisteredBoundId GetBoundId() const { return m_boundId; } + RegisteredBoundId GetBoundId() const + { + return m_boundId; + } - /** - * @param rayOrigin The origin of the ray to test with. - * @param rayDir The direction of the ray to test with. - * @param[out] rayIntersectionDistance The distance of the intersecting point closest to the ray origin. - * @return Boolean indicating whether there is a least one intersecting point between this bound shape and the ray. - */ - virtual bool IntersectRay( - const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) = 0; + //! @param rayOrigin The origin of the ray to test with. + //! @param rayDir The direction of the ray to test with. + //! @param[out] rayIntersectionDistance The distance of the intersecting point closest to the ray origin. + //! @return Boolean indicating whether there is a least one intersecting point between this bound shape and the ray. + virtual bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) = 0; virtual void SetShapeData(const BoundRequestShapeBase& shapeData) = 0; - void SetValidity(bool valid) { m_valid = valid; } - bool IsValid() const { return m_valid; } + void SetValidity(bool valid) + { + m_valid = valid; + } + + bool IsValid() const + { + return m_valid; + } private: RegisteredBoundId m_boundId; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/ContextBoundAPI.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/ContextBoundAPI.h index 4a053ea758..7127ac82ee 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/ContextBoundAPI.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/ContextBoundAPI.h @@ -1,22 +1,22 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once #include -#include #include #include #include +#include #include #include #include @@ -27,9 +27,7 @@ namespace AzToolsFramework { namespace Picking { - /** - * An interface concrete shape types can implement to create specific BoundShapeInterfaces. - */ + //! An interface concrete shape types can implement to create specific BoundShapeInterfaces. class BoundRequestShapeBase { public: @@ -114,11 +112,9 @@ namespace AzToolsFramework float m_radius; }; - /** - * The quad shape consists of 4 points in 3D space. Please set them from \ref m_corner1 to \ref m_corner4 - * in either clock-wise winding or counter clock-wise winding. In another word, \ref m_corner1 and - * \ref corner_2 cannot be diagonal corners. - */ + //! The quad shape consists of 4 points in 3D space. Please set them from \ref m_corner1 to \ref m_corner4 + //! in either clock-wise winding or counter clock-wise winding. In another word, \ref m_corner1 and + //! \ref corner_2 cannot be diagonal corners. class BoundShapeQuad : public BoundRequestShapeBase { public: @@ -138,9 +134,7 @@ namespace AzToolsFramework AZ::Vector3 m_corner4; }; - /** - * The line segment consists of two points in 3D space defining a line the user can interact with. - */ + //! The line segment consists of two points in 3D space defining a line the user can interact with. class BoundShapeLineSegment : public BoundRequestShapeBase { public: @@ -159,10 +153,8 @@ namespace AzToolsFramework float m_width; }; - /** - * The torus shape is approximated by a cylinder whose radius is the sum of the torus's major radius - * and minor radius and height is twice the torus's minor radius. - */ + //! The torus shape is approximated by a cylinder whose radius is the sum of the torus's major radius + //! and minor radius and height is twice the torus's minor radius. class BoundShapeTorus : public BoundRequestShapeBase { public: @@ -182,10 +174,8 @@ namespace AzToolsFramework float m_minorRadius; }; - /** - * The spline is specified by a number of vertices. A piecewise approximation of the curve - * is computed by using a number of linear steps (defined by the granularity of the curve). - */ + //! The spline is specified by a number of vertices. A piecewise approximation of the curve + //! is computed by using a number of linear steps (defined by the granularity of the curve). class BoundShapeSpline : public BoundRequestShapeBase { public: @@ -204,16 +194,14 @@ namespace AzToolsFramework float m_width; }; - /** - * Ray query for intersection against bounds. - */ + //! Ray query for intersection against bounds. struct RaySelectInfo { - AZ::Vector3 m_origin; ///< Start of ray. - AZ::Vector3 m_direction; ///< Direction of ray - make sure m_direction is unit length. - AZStd::vector> m_boundIdsHit; ///< Store the id of the intersected bound - ///< and the parameter of the corresponding - ///< intersecting point. + AZ::Vector3 m_origin; //!< Start of ray. + AZ::Vector3 m_direction; //!< Direction of ray - make sure m_direction is unit length. + AZStd::vector> m_boundIdsHit; //!< Store the id of the intersected bound + //!< and the parameter of the corresponding + //!< intersecting point. }; } // namespace Picking } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBoundManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBoundManager.cpp index d838413a67..342dc4b99e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBoundManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBoundManager.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "ManipulatorBoundManager.h" @@ -16,8 +16,7 @@ namespace AzToolsFramework { namespace Picking { - RegisteredBoundId ManipulatorBoundManager::UpdateOrRegisterBound( - const BoundRequestShapeBase& shapeData, RegisteredBoundId boundId) + RegisteredBoundId ManipulatorBoundManager::UpdateOrRegisterBound(const BoundRequestShapeBase& shapeData, RegisteredBoundId boundId) { if (boundId == InvalidBoundId) { @@ -25,8 +24,7 @@ namespace AzToolsFramework boundId = m_nextBoundId++; } - if (auto result = m_boundIdToShapeMap.find(boundId); - result == m_boundIdToShapeMap.end()) + if (auto result = m_boundIdToShapeMap.find(boundId); result == m_boundIdToShapeMap.end()) { if (AZStd::shared_ptr createdShape = CreateShape(shapeData, boundId)) { @@ -49,19 +47,16 @@ namespace AzToolsFramework void ManipulatorBoundManager::UnregisterBound(const RegisteredBoundId boundId) { - if (const auto findIter = m_boundIdToShapeMap.find(boundId); - findIter != m_boundIdToShapeMap.end()) + if (const auto findIter = m_boundIdToShapeMap.find(boundId); findIter != m_boundIdToShapeMap.end()) { DeleteShape(findIter->second.get()); m_boundIdToShapeMap.erase(findIter); } } - void ManipulatorBoundManager::SetBoundValidity( - const RegisteredBoundId boundId, const bool valid) + void ManipulatorBoundManager::SetBoundValidity(const RegisteredBoundId boundId, const bool valid) { - if (auto found = m_boundIdToShapeMap.find(boundId); - found != m_boundIdToShapeMap.end()) + if (auto found = m_boundIdToShapeMap.find(boundId); found != m_boundIdToShapeMap.end()) { found->second->SetValidity(valid); } @@ -104,9 +99,9 @@ namespace AzToolsFramework const auto hitItr = AZStd::lower_bound( rayHits.begin(), rayHits.end(), BoundIdHitDistance(0, t), [](const BoundIdHitDistance& lhs, const BoundIdHitDistance& rhs) - { - return lhs.second < rhs.second; - }); + { + return lhs.second < rhs.second; + }); rayHits.insert(hitItr, AZStd::make_pair(bound->GetBoundId(), t)); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBoundManager.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBoundManager.h index 78e714c256..504f06bb49 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBoundManager.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBoundManager.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -21,10 +21,8 @@ namespace AzToolsFramework { class BoundShapeInterface; - /** - * Handle creating, destroying and storing all active manipulator - * bounds for performing raycasts/picking against. - */ + //! Handle creating, destroying and storing all active manipulator + //! bounds for performing raycasts/picking against. class ManipulatorBoundManager { public: @@ -35,21 +33,19 @@ namespace AzToolsFramework ManipulatorBoundManager& operator=(const ManipulatorBoundManager&) = delete; ~ManipulatorBoundManager() = default; - RegisteredBoundId UpdateOrRegisterBound( - const BoundRequestShapeBase& shapeData, RegisteredBoundId id); + RegisteredBoundId UpdateOrRegisterBound(const BoundRequestShapeBase& shapeData, RegisteredBoundId id); void UnregisterBound(RegisteredBoundId boundId); void SetBoundValidity(RegisteredBoundId boundId, bool valid); - void RaySelect(RaySelectInfo &rayInfo); + void RaySelect(RaySelectInfo& rayInfo); private: - AZStd::shared_ptr CreateShape( - const BoundRequestShapeBase& ptrShape, RegisteredBoundId id); + AZStd::shared_ptr CreateShape(const BoundRequestShapeBase& ptrShape, RegisteredBoundId id); void DeleteShape(const BoundShapeInterface* boundShape); AZStd::unordered_map> m_boundIdToShapeMap; - AZStd::vector> m_bounds; ///< All current manipulator bounds. + AZStd::vector> m_bounds; //!< All current manipulator bounds. - RegisteredBoundId m_nextBoundId = RegisteredBoundId(1); ///< Next bound id to use when a bound is registered. + RegisteredBoundId m_nextBoundId = RegisteredBoundId(1); //!< Next bound id to use when a bound is registered. }; } // namespace Picking } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBounds.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBounds.cpp index 8a9ebbacbc..8dca45cc9a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBounds.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBounds.cpp @@ -1,17 +1,18 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include #include +#include #include #include @@ -23,8 +24,7 @@ namespace AzToolsFramework const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, float& rayIntersectionDistance) { float vecRayIntersectionDistance; - if (AZ::Intersect::IntersectRaySphere( - rayOrigin, rayDirection, m_center, m_radius, vecRayIntersectionDistance) > 0) + if (AZ::Intersect::IntersectRaySphere(rayOrigin, rayDirection, m_center, m_radius, vecRayIntersectionDistance) > 0) { rayIntersectionDistance = vecRayIntersectionDistance; return true; @@ -45,8 +45,9 @@ namespace AzToolsFramework bool ManipulatorBoundBox::IntersectRay( const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, float& rayIntersectionDistance) { - return AZ::Intersect::IntersectRayBox(rayOrigin, rayDirection, m_center, m_axis1, m_axis2, m_axis3, - m_halfExtents.GetX(), m_halfExtents.GetY(), m_halfExtents.GetZ(), rayIntersectionDistance) > 0; + return AZ::Intersect::IntersectRayBox( + rayOrigin, rayDirection, m_center, m_axis1, m_axis2, m_axis3, m_halfExtents.GetX(), m_halfExtents.GetY(), + m_halfExtents.GetZ(), rayIntersectionDistance) > 0; } void ManipulatorBoundBox::SetShapeData(const BoundRequestShapeBase& shapeData) @@ -66,8 +67,7 @@ namespace AzToolsFramework { float t1 = std::numeric_limits::max(); float t2 = std::numeric_limits::max(); - if (AZ::Intersect::IntersectRayCappedCylinder( - rayOrigin, rayDirection, m_base, m_axis, m_height, m_radius, t1, t2) > 0) + if (AZ::Intersect::IntersectRayCappedCylinder(rayOrigin, rayDirection, m_base, m_axis, m_height, m_radius, t1, t2) > 0) { rayIntersectionDistance = AZStd::GetMin(t1, t2); return true; @@ -92,8 +92,7 @@ namespace AzToolsFramework { float t1 = std::numeric_limits::max(); float t2 = std::numeric_limits::max(); - if (AZ::Intersect::IntersectRayCone( - rayOrigin, rayDirection, m_apexPosition, m_dir, m_height, m_radius, t1, t2) > 0) + if (AZ::Intersect::IntersectRayCone(rayOrigin, rayDirection, m_apexPosition, m_dir, m_height, m_radius, t1, t2) > 0) { rayIntersectionDistance = AZStd::GetMin(t1, t2); return true; @@ -117,7 +116,7 @@ namespace AzToolsFramework const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, float& rayIntersectionDistance) { return AZ::Intersect::IntersectRayQuad( - rayOrigin, rayDirection, m_corner1, m_corner2, m_corner3, m_corner4, rayIntersectionDistance) > 0; + rayOrigin, rayDirection, m_corner1, m_corner2, m_corner3, m_corner4, rayIntersectionDistance) > 0; } void ManipulatorBoundQuad::SetShapeData(const BoundRequestShapeBase& shapeData) @@ -157,8 +156,7 @@ namespace AzToolsFramework float rayProportion, lineSegmentProportion; // note: here out param is proportion/percentage of line AZ::Intersect::ClosestSegmentSegment( - rayOrigin, rayOrigin + rayDirection * rayLength, - m_worldStart, m_worldEnd, rayProportion, lineSegmentProportion, + rayOrigin, rayOrigin + rayDirection * rayLength, m_worldStart, m_worldEnd, rayProportion, lineSegmentProportion, closestPosRay, closestPosLineSegment); float distanceFromLine = (closestPosRay - closestPosLineSegment).GetLength(); @@ -188,8 +186,7 @@ namespace AzToolsFramework { if (const AZStd::shared_ptr spline = m_spline.lock()) { - AZ::RaySplineQueryResult splineQueryResult = - AZ::IntersectSpline(m_transform, rayOrigin, rayDirection, *spline); + AZ::RaySplineQueryResult splineQueryResult = AZ::IntersectSpline(m_transform, rayOrigin, rayDirection, *spline); if (splineQueryResult.m_distanceSq <= m_width * m_width) { @@ -214,22 +211,25 @@ namespace AzToolsFramework } bool IntersectHollowCylinder( - const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, - const AZ::Vector3& center, const AZ::Vector3& axis, - const float minorRadius, const float majorRadius, + const AZ::Vector3& rayOrigin, + const AZ::Vector3& rayDirection, + const AZ::Vector3& center, + const AZ::Vector3& axis, + const float minorRadius, + const float majorRadius, float& rayIntersectionDistance) { - float t1 = std::numeric_limits::max(); - float t2 = std::numeric_limits::max(); + float t1 = AZStd::numeric_limits::max(); + float t2 = AZStd::numeric_limits::max(); const AZ::Vector3 base = center - axis * minorRadius; if (AZ::Intersect::IntersectRayCappedCylinder( - rayOrigin, rayDirection, base, axis, minorRadius * 2.0f, majorRadius + minorRadius, t1, t2) > 0) + rayOrigin, rayDirection, base, axis, minorRadius * 2.0f, majorRadius + minorRadius, t1, t2) > 0) { - const float thresholdSq = powf(majorRadius - minorRadius, 2.0f); + const float threshold = majorRadius - minorRadius; + const float thresholdSq = threshold * threshold; // util lambda used for distance checks at both 't' values - const auto validHolowCylinderHit = - [&rayOrigin, &rayDirection, ¢er, thresholdSq](const float t) + const auto validHolowCylinderHit = [&rayOrigin, &rayDirection, ¢er, thresholdSq](const float t) { // only return a valid intersection if the hit was // not in the 'hollow' part of the cylinder diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBounds.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBounds.h index ca9eeded11..d72e11fd0a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBounds.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Picking/Manipulators/ManipulatorBounds.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -27,36 +27,36 @@ namespace AzToolsFramework { namespace Picking { - class ManipulatorBoundSphere - : public BoundShapeInterface + class ManipulatorBoundSphere : public BoundShapeInterface { public: AZ_RTTI(ManipulatorBoundSphere, "{64D1B863-F574-4B31-A4F2-C9744D8567B3}", BoundShapeInterface); AZ_CLASS_ALLOCATOR(ManipulatorBoundSphere, AZ::SystemAllocator, 0); explicit ManipulatorBoundSphere(RegisteredBoundId boundId) - : BoundShapeInterface(boundId) {} + : BoundShapeInterface(boundId) + { + } - bool IntersectRay( - const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; + bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; void SetShapeData(const BoundRequestShapeBase& shapeData) override; AZ::Vector3 m_center = AZ::Vector3::CreateZero(); float m_radius = 0.0f; }; - class ManipulatorBoundBox - : public BoundShapeInterface + class ManipulatorBoundBox : public BoundShapeInterface { public: AZ_RTTI(ManipulatorBoundBox, "{3AD46067-933F-49B4-82E1-DBF12C7BC02E}", BoundShapeInterface); AZ_CLASS_ALLOCATOR(ManipulatorBoundBox, AZ::SystemAllocator, 0); explicit ManipulatorBoundBox(RegisteredBoundId boundId) - : BoundShapeInterface(boundId) {} + : BoundShapeInterface(boundId) + { + } - bool IntersectRay( - const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; + bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; void SetShapeData(const BoundRequestShapeBase& shapeData) override; AZ::Vector3 m_center = AZ::Vector3::CreateZero(); @@ -66,38 +66,38 @@ namespace AzToolsFramework AZ::Vector3 m_halfExtents = AZ::Vector3::CreateZero(); }; - class ManipulatorBoundCylinder - : public BoundShapeInterface + class ManipulatorBoundCylinder : public BoundShapeInterface { public: AZ_RTTI(ManipulatorBoundCylinder, "{D248F9E4-22E6-41A8-898D-704DF307B533}", BoundShapeInterface); AZ_CLASS_ALLOCATOR(ManipulatorBoundCylinder, AZ::SystemAllocator, 0); explicit ManipulatorBoundCylinder(RegisteredBoundId boundId) - : BoundShapeInterface(boundId) {} + : BoundShapeInterface(boundId) + { + } - bool IntersectRay( - const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; + bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; void SetShapeData(const BoundRequestShapeBase& shapeData) override; - AZ::Vector3 m_base = AZ::Vector3::CreateZero(); ///< The center of the circle at the base of the cylinder. + AZ::Vector3 m_base = AZ::Vector3::CreateZero(); //!< The center of the circle at the base of the cylinder. AZ::Vector3 m_axis = AZ::Vector3::CreateZero(); float m_height = 0.0f; float m_radius = 0.0f; }; - class ManipulatorBoundCone - : public BoundShapeInterface + class ManipulatorBoundCone : public BoundShapeInterface { public: AZ_RTTI(ManipulatorBoundCone, "{9430440D-DFF2-4A60-9073-507C4E9DD65D}", BoundShapeInterface); AZ_CLASS_ALLOCATOR(ManipulatorBoundCone, AZ::SystemAllocator, 0); explicit ManipulatorBoundCone(RegisteredBoundId boundId) - : BoundShapeInterface(boundId) {} + : BoundShapeInterface(boundId) + { + } - bool IntersectRay( - const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; + bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; void SetShapeData(const BoundRequestShapeBase& shapeData) override; AZ::Vector3 m_apexPosition = AZ::Vector3::CreateZero(); @@ -106,23 +106,21 @@ namespace AzToolsFramework float m_height = 0.0f; }; - /** - * The quad shape consists of 4 points in 3D space. Please set them from \ref m_corner1 to \ref m_corner4 - * in either clock-wise winding or counter clock-wise winding. In another word, \ref m_corner1 and - * \ref corner_2 cannot be diagonal corners. - */ - class ManipulatorBoundQuad - : public BoundShapeInterface + //! The quad shape consists of 4 points in 3D space. Please set them from \ref m_corner1 to \ref m_corner4 + //! in either clock-wise winding or counter clock-wise winding. In another word, \ref m_corner1 and + //! \ref corner_2 cannot be diagonal corners. + class ManipulatorBoundQuad : public BoundShapeInterface { public: AZ_RTTI(ManipulatorBoundQuad, "{3CDED61C-5786-4299-B5F2-5970DE4457AD}", BoundShapeInterface); AZ_CLASS_ALLOCATOR(ManipulatorBoundQuad, AZ::SystemAllocator, 0); explicit ManipulatorBoundQuad(RegisteredBoundId boundId) - : BoundShapeInterface(boundId) {} + : BoundShapeInterface(boundId) + { + } - bool IntersectRay( - const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; + bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; void SetShapeData(const BoundRequestShapeBase& shapeData) override; AZ::Vector3 m_corner1 = AZ::Vector3::CreateZero(); @@ -131,18 +129,18 @@ namespace AzToolsFramework AZ::Vector3 m_corner4 = AZ::Vector3::CreateZero(); }; - class ManipulatorBoundTorus - : public BoundShapeInterface + class ManipulatorBoundTorus : public BoundShapeInterface { public: AZ_RTTI(ManipulatorBoundTorus, "{46E4711C-178A-4F97-BC14-A048D096E7A1}", BoundShapeInterface); AZ_CLASS_ALLOCATOR(ManipulatorBoundTorus, AZ::SystemAllocator, 0); explicit ManipulatorBoundTorus(RegisteredBoundId boundId) - : BoundShapeInterface(boundId) {} + : BoundShapeInterface(boundId) + { + } - bool IntersectRay( - const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; + bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; void SetShapeData(const BoundRequestShapeBase& shapeData) override; // Approximate a torus as a thin cylinder. A ray intersects a torus when the ray and the torus' @@ -150,22 +148,22 @@ namespace AzToolsFramework // center of the torus. AZ::Vector3 m_center = AZ::Vector3::CreateZero(); AZ::Vector3 m_axis = AZ::Vector3::CreateZero(); - float m_majorRadius = 0.0f; ///< Usually denoted as "R", the distance from the center of the tube to the center of the torus. - float m_minorRadius = 0.0f; ///< Usually denoted as "r", the radius of the tube. + float m_majorRadius = 0.0f; //!< Usually denoted as "R", the distance from the center of the tube to the center of the torus. + float m_minorRadius = 0.0f; //!< Usually denoted as "r", the radius of the tube. }; - class ManipulatorBoundLineSegment - : public BoundShapeInterface + class ManipulatorBoundLineSegment : public BoundShapeInterface { public: AZ_RTTI(ManipulatorBoundLineSegment, "{66801554-1C1A-4E79-B1E7-342DFA779D53}", BoundShapeInterface); AZ_CLASS_ALLOCATOR(ManipulatorBoundLineSegment, AZ::SystemAllocator, 0); explicit ManipulatorBoundLineSegment(RegisteredBoundId boundId) - : BoundShapeInterface(boundId) {} + : BoundShapeInterface(boundId) + { + } - bool IntersectRay( - const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; + bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; void SetShapeData(const BoundRequestShapeBase& shapeData) override; AZ::Vector3 m_worldStart = AZ::Vector3::CreateZero(); @@ -173,18 +171,18 @@ namespace AzToolsFramework float m_width = 0.0f; }; - class ManipulatorBoundSpline - : public BoundShapeInterface + class ManipulatorBoundSpline : public BoundShapeInterface { public: AZ_RTTI(ManipulatorBoundSpline, "{777760FF-8547-45AD-876F-16BA4D9D0584}", BoundShapeInterface); AZ_CLASS_ALLOCATOR(ManipulatorBoundSpline, AZ::SystemAllocator, 0); explicit ManipulatorBoundSpline(RegisteredBoundId boundId) - : BoundShapeInterface(boundId) {} + : BoundShapeInterface(boundId) + { + } - bool IntersectRay( - const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; + bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override; void SetShapeData(const BoundRequestShapeBase& shapeData) override; AZStd::weak_ptr m_spline; @@ -192,11 +190,14 @@ namespace AzToolsFramework float m_width = 0.0f; }; - /// Approximate intersection with a torus-like shape. + //! Approximate intersection with a torus-like shape. bool IntersectHollowCylinder( - const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, - const AZ::Vector3& center, const AZ::Vector3& axis, - float minorRadius, float majorRadius, + const AZ::Vector3& rayOrigin, + const AZ::Vector3& rayDirection, + const AZ::Vector3& center, + const AZ::Vector3& axis, + float minorRadius, + float majorRadius, float& rayIntersectionDistance); } // namespace Picking diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/EditorContextMenu.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/EditorContextMenu.cpp index 7fa9724d65..8ed488b010 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/EditorContextMenu.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/EditorContextMenu.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "EditorContextMenu.h" @@ -16,8 +16,7 @@ namespace AzToolsFramework { - void EditorContextMenuUpdate( - EditorContextMenu& contextMenu, const ViewportInteraction::MouseInteractionEvent& mouseInteraction) + void EditorContextMenuUpdate(EditorContextMenu& contextMenu, const ViewportInteraction::MouseInteractionEvent& mouseInteraction) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -26,18 +25,17 @@ namespace AzToolsFramework mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down) { contextMenu.m_shouldOpen = true; - contextMenu.m_clickPoint = ViewportInteraction::QPointFromScreenPoint( - mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates); + contextMenu.m_clickPoint = + ViewportInteraction::QPointFromScreenPoint(mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates); } // disable shouldOpen if right clicking an moving the mouse if (mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Move) { - const QPoint currentScreenCoords = ViewportInteraction::QPointFromScreenPoint( - mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates); + const QPoint currentScreenCoords = + ViewportInteraction::QPointFromScreenPoint(mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates); - contextMenu.m_shouldOpen = contextMenu.m_shouldOpen && - (currentScreenCoords - contextMenu.m_clickPoint).manhattanLength() < 2; + contextMenu.m_shouldOpen = contextMenu.m_shouldOpen && (currentScreenCoords - contextMenu.m_clickPoint).manhattanLength() < 2; } // do show the context menu @@ -58,9 +56,8 @@ namespace AzToolsFramework // Populate global context menu. const int contextMenuFlag = 0; EditorEvents::Bus::BroadcastReverse( - &EditorEvents::PopulateEditorGlobalContextMenu, - contextMenu.m_menu.data(), AzFramework::Vector2FromScreenPoint( - mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates), + &EditorEvents::PopulateEditorGlobalContextMenu, contextMenu.m_menu.data(), + AzFramework::Vector2FromScreenPoint(mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates), contextMenuFlag); if (!contextMenu.m_menu->isEmpty()) @@ -70,4 +67,4 @@ namespace AzToolsFramework } } } -} +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/EditorContextMenu.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/EditorContextMenu.h index ebce02fa4c..ff5bffc544 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/EditorContextMenu.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/EditorContextMenu.h @@ -1,22 +1,22 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once #include +#include #include #include -#include namespace AzToolsFramework { @@ -25,7 +25,7 @@ namespace AzToolsFramework struct MouseInteractionEvent; } - /// State of when and where the right-click context menu should appear. + //! State of when and where the right-click context menu should appear. struct EditorContextMenu final { bool m_shouldOpen = false; @@ -33,8 +33,6 @@ namespace AzToolsFramework QPointer m_menu; }; - /// Update to run for context menu (when should it appear/disappear etc). - void EditorContextMenuUpdate( - EditorContextMenu& contextMenu, - const ViewportInteraction::MouseInteractionEvent& mouseInteraction); + //! Update to run for context menu (when should it appear/disappear etc). + void EditorContextMenuUpdate(EditorContextMenu& contextMenu, const ViewportInteraction::MouseInteractionEvent& mouseInteraction); } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/VertexContainerDisplay.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/VertexContainerDisplay.cpp index cd9382c497..10016fbb13 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/VertexContainerDisplay.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/VertexContainerDisplay.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "VertexContainerDisplay.h" @@ -23,8 +23,7 @@ namespace AzToolsFramework const AZ::Vector3 DefaultVertexTextOffset = AZ::Vector3(0.0f, 0.0f, -0.1f); void DisplayVertexContainerIndex( - AzFramework::DebugDisplayRequests& debugDisplay, - const AZ::Vector3& position, const size_t index, const float textSize) + AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position, const size_t index, const float textSize) { AZStd::string indexFormat = AZStd::string::format("[%zu]", index); debugDisplay.DrawTextLabel(position, textSize, indexFormat.c_str(), true); @@ -36,7 +35,8 @@ namespace AzToolsFramework const AZ::FixedVertices& vertices, const AZ::Transform& transform, const AZ::Vector3& nonUniformScale, - const bool selected, const float textSize, + const bool selected, + const float textSize, const AZ::Color& textColor, const AZ::Vector3& textOffset) { @@ -52,11 +52,12 @@ namespace AzToolsFramework if (vertices.GetVertex(vertIndex, vertex)) { DisplayVertexContainerIndex( - debugDisplay, transform.TransformPoint(nonUniformScale * (AdaptVertexOut(vertex) + textOffset)), vertIndex, textSize); + debugDisplay, transform.TransformPoint(nonUniformScale * (AdaptVertexOut(vertex) + textOffset)), vertIndex, + textSize); } } } - } + } // namespace VertexContainerDisplay // explicit template instantiations template void VertexContainerDisplay::DisplayVertexContainerIndices( @@ -64,7 +65,8 @@ namespace AzToolsFramework const AZ::FixedVertices& vertices, const AZ::Transform& transform, const AZ::Vector3& nonUniformScale, - bool selected, float textSize, + bool selected, + float textSize, const AZ::Color& textColor, const AZ::Vector3& textOffset); template void VertexContainerDisplay::DisplayVertexContainerIndices( @@ -72,7 +74,8 @@ namespace AzToolsFramework const AZ::FixedVertices& vertices, const AZ::Transform& transform, const AZ::Vector3& nonUniformScale, - bool selected, float textSize, + bool selected, + float textSize, const AZ::Color& textColor, const AZ::Vector3& textOffset); -} +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/VertexContainerDisplay.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/VertexContainerDisplay.h index 1717d770df..c734740d3c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/VertexContainerDisplay.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/VertexContainerDisplay.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -22,22 +22,23 @@ namespace AzFramework namespace AzToolsFramework { - /// Utility functions for rendering vertex container indices. + //! Utility functions for rendering vertex container indices. namespace VertexContainerDisplay { extern const float DefaultVertexTextSize; extern const AZ::Color DefaultVertexTextColor; extern const AZ::Vector3 DefaultVertexTextOffset; - /// Displays all vertex container indices as text at the position of each vertex when selected + //! Displays all vertex container indices as text at the position of each vertex when selected template void DisplayVertexContainerIndices( AzFramework::DebugDisplayRequests& debugDisplay, const AZ::FixedVertices& vertices, const AZ::Transform& transform, const AZ::Vector3& nonUniformScale, - bool selected, float textSize = DefaultVertexTextSize, + bool selected, + float textSize = DefaultVertexTextSize, const AZ::Color& textColor = DefaultVertexTextColor, const AZ::Vector3& textOffset = DefaultVertexTextOffset); - } + } // namespace VertexContainerDisplay } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h index 91eee18cb7..85250f2a32 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -17,8 +17,8 @@ #include #include #include -#include #include +#include #include #include @@ -31,45 +31,51 @@ namespace AzToolsFramework { namespace ViewportInteraction { - /// Result of handling mouse interaction. + //! Result of handling mouse interaction. enum class MouseInteractionResult { - Manipulator, ///< The manipulator manager handled the interaction. - Viewport, ///< The viewport handled the interaction. - None ///< The interaction was not handled. + Manipulator, //!< The manipulator manager handled the interaction. + Viewport, //!< The viewport handled the interaction. + None //!< The interaction was not handled. }; - /// Interface for handling mouse viewport events. + //! Interface for handling mouse viewport events. class MouseViewportRequests { public: - /// @cond + //! @cond virtual ~MouseViewportRequests() = default; - /// @endcond + //! @endcond - /// Implement this function to handle a particular mouse event. - virtual bool HandleMouseInteraction( - const MouseInteractionEvent& /*mouseInteraction*/) { return false; } + //! Implement this function to handle a particular mouse event. + virtual bool HandleMouseInteraction(const MouseInteractionEvent& /*mouseInteraction*/) + { + return false; + } }; - - /// Interface for internal handling mouse viewport events. + + //! Interface for internal handling mouse viewport events. class InternalMouseViewportRequests { public: - /// @cond + //! @cond virtual ~InternalMouseViewportRequests() = default; - /// @endcond + //! @endcond - /// Implement this function to have the viewport handle this mouse event. - virtual bool InternalHandleMouseViewportInteraction( - const MouseInteractionEvent& /*mouseInteraction*/) { return false; } + //! Implement this function to have the viewport handle this mouse event. + virtual bool InternalHandleMouseViewportInteraction(const MouseInteractionEvent& /*mouseInteraction*/) + { + return false; + } - /// Implement this function to have manipulators handle this mouse event. - virtual bool InternalHandleMouseManipulatorInteraction( - const MouseInteractionEvent& /*mouseInteraction*/) { return false; } + //! Implement this function to have manipulators handle this mouse event. + virtual bool InternalHandleMouseManipulatorInteraction(const MouseInteractionEvent& /*mouseInteraction*/) + { + return false; + } - /// Helper to call both viewport and manipulator handle mouse events - /// @note Manipulators always attempt to intercept the event first. + //! Helper to call both viewport and manipulator handle mouse events + //! @note Manipulators always attempt to intercept the event first. MouseInteractionResult InternalHandleAllMouseInteractions(const MouseInteractionEvent& mouseInteraction); }; @@ -90,117 +96,118 @@ namespace AzToolsFramework } } - /// Interface for viewport selection behaviors. + //! Interface for viewport selection behaviors. class ViewportDisplayNotifications { public: - /// @cond + //! @cond virtual ~ViewportDisplayNotifications() = default; - /// @endcond - - /// Display drawing in world space. - /// \ref DisplayViewportSelection is called from \ref EditorInteractionSystemComponent::DisplayViewport. - /// DisplayViewport exists on the \ref AzFramework::ViewportDebugDisplayEventBus and is called from \ref CRenderViewport. - /// \ref DisplayViewportSelection is called after \ref CalculateVisibleEntityDatas on the \ref EditorVisibleEntityDataCache, - /// this ensures usage of the entity cache will be up to date (do not implement \ref AzFramework::ViewportDebugDisplayEventBus - /// directly if wishing to use the \ref EditorVisibleEntityDataCache). + //! @endcond + + //! Display drawing in world space. + //! \ref DisplayViewportSelection is called from \ref EditorInteractionSystemComponent::DisplayViewport. + //! DisplayViewport exists on the \ref AzFramework::ViewportDebugDisplayEventBus and is called from \ref CRenderViewport. + //! \ref DisplayViewportSelection is called after \ref CalculateVisibleEntityDatas on the \ref EditorVisibleEntityDataCache, + //! this ensures usage of the entity cache will be up to date (do not implement \ref AzFramework::ViewportDebugDisplayEventBus + //! directly if wishing to use the \ref EditorVisibleEntityDataCache). virtual void DisplayViewportSelection( - const AzFramework::ViewportInfo& /*viewportInfo*/, - AzFramework::DebugDisplayRequests& /*debugDisplay*/) {} - /// Display drawing in screen space. - /// \ref DisplayViewportSelection2d is called after \ref DisplayViewportSelection when the viewport has been - /// configured to be orthographic in \ref CRenderViewport. All screen space drawing can be performed here. + const AzFramework::ViewportInfo& /*viewportInfo*/, AzFramework::DebugDisplayRequests& /*debugDisplay*/) + { + } + //! Display drawing in screen space. + //! \ref DisplayViewportSelection2d is called after \ref DisplayViewportSelection when the viewport has been + //! configured to be orthographic in \ref CRenderViewport. All screen space drawing can be performed here. virtual void DisplayViewportSelection2d( - const AzFramework::ViewportInfo& /*viewportInfo*/, - AzFramework::DebugDisplayRequests& /*debugDisplay*/) {} + const AzFramework::ViewportInfo& /*viewportInfo*/, AzFramework::DebugDisplayRequests& /*debugDisplay*/) + { + } }; - /// Interface for internal handling mouse viewport events and display notifications. - /// Implement this for types wishing to provide viewport functionality and - /// set it by using \ref EditorInteractionSystemViewportSelectionRequestBus. + //! Interface for internal handling mouse viewport events and display notifications. + //! Implement this for types wishing to provide viewport functionality and + //! set it by using \ref EditorInteractionSystemViewportSelectionRequestBus. class InternalViewportSelectionRequests : public ViewportDisplayNotifications , public InternalMouseViewportRequests { }; - /// Interface for handling mouse viewport events and display notifications. - /// Use this interface for composition types used by InternalViewportSelectionRequests. + //! Interface for handling mouse viewport events and display notifications. + //! Use this interface for composition types used by InternalViewportSelectionRequests. class ViewportSelectionRequests : public ViewportDisplayNotifications , public MouseViewportRequests { }; - /// The EBusTraits for ViewportInteractionRequests. - class ViewportEBusTraits - : public AZ::EBusTraits + //! The EBusTraits for ViewportInteractionRequests. + class ViewportEBusTraits : public AZ::EBusTraits { public: - using BusIdType = AzFramework::ViewportId; ///< ViewportId - used to address requests to this EBus. + using BusIdType = AzFramework::ViewportId; //!< ViewportId - used to address requests to this EBus. static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; }; - /// A ray projection, originating from a point and extending in a direction specified as a normal. + //! A ray projection, originating from a point and extending in a direction specified as a normal. struct ProjectedViewportRay { AZ::Vector3 origin; AZ::Vector3 direction; }; - /// Requests that can be made to the viewport to query and modify its state. + //! Requests that can be made to the viewport to query and modify its state. class ViewportInteractionRequests { public: - /// Return the current camera state for this viewport. + //! Return the current camera state for this viewport. virtual AzFramework::CameraState GetCameraState() = 0; - /// Return if grid snapping is enabled. + //! Return if grid snapping is enabled. virtual bool GridSnappingEnabled() = 0; - /// Return the grid snapping size. + //! Return the grid snapping size. virtual float GridSize() = 0; - /// Does the grid currently want to be displayed. + //! Does the grid currently want to be displayed. virtual bool ShowGrid() = 0; - /// Return if angle snapping is enabled. + //! Return if angle snapping is enabled. virtual bool AngleSnappingEnabled() = 0; - /// Return the angle snapping/step size. + //! Return the angle snapping/step size. virtual float AngleStep() = 0; - /// Transform a point in world space to screen space coordinates in Qt Widget space. - /// Multiply by DeviceScalingFactor to get the position in viewport pixel space. + //! Transform a point in world space to screen space coordinates in Qt Widget space. + //! Multiply by DeviceScalingFactor to get the position in viewport pixel space. virtual AzFramework::ScreenPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition) = 0; - /// Transform a point from Qt widget screen space to world space based on the given clip space depth. - /// Depth specifies a relative camera depth to project in the range of [0.f, 1.f]. - /// Returns the world space position if successful. + //! Transform a point from Qt widget screen space to world space based on the given clip space depth. + //! Depth specifies a relative camera depth to project in the range of [0.f, 1.f]. + //! Returns the world space position if successful. virtual AZStd::optional ViewportScreenToWorld(const AzFramework::ScreenPoint& screenPosition, float depth) = 0; - /// Casts a point in screen space to a ray in world space originating from the viewport camera frustum's near plane. - /// Returns a ray containing the ray's origin and a direction normal, if successful. + //! Casts a point in screen space to a ray in world space originating from the viewport camera frustum's near plane. + //! Returns a ray containing the ray's origin and a direction normal, if successful. virtual AZStd::optional ViewportScreenToWorldRay(const AzFramework::ScreenPoint& screenPosition) = 0; - /// Gets the DPI scaling factor that translates Qt widget space into viewport pixel space. + //! Gets the DPI scaling factor that translates Qt widget space into viewport pixel space. virtual float DeviceScalingFactor() = 0; protected: ~ViewportInteractionRequests() = default; }; - /// Interface to return only viewport specific settings (e.g. snapping). + //! Interface to return only viewport specific settings (e.g. snapping). class ViewportSettings { public: virtual ~ViewportSettings() = default; - /// Return if grid snapping is enabled. + //! Return if grid snapping is enabled. virtual bool GridSnappingEnabled() const = 0; - /// Return the grid snapping size. + //! Return the grid snapping size. virtual float GridSize() const = 0; - /// Does the grid currently want to be displayed. + //! Does the grid currently want to be displayed. virtual bool ShowGrid() const = 0; - /// Return if angle snapping is enabled. + //! Return if angle snapping is enabled. virtual bool AngleSnappingEnabled() const = 0; - /// Return the angle snapping/step size. + //! Return the angle snapping/step size. virtual float AngleStep() const = 0; }; - /// Type to inherit to implement ViewportInteractionRequests. + //! Type to inherit to implement ViewportInteractionRequests. using ViewportInteractionRequestBus = AZ::EBus; //! Requests to freeze the Viewport Input @@ -221,62 +228,62 @@ namespace AzToolsFramework //! Type to inherit to implement ViewportFreezeRequests. using ViewportFreezeRequestBus = AZ::EBus; - /// Viewport requests that are only guaranteed to be serviced by the Main Editor viewport. + //! Viewport requests that are only guaranteed to be serviced by the Main Editor viewport. class MainEditorViewportInteractionRequests { public: - /// Given a point in screen space, return the picked entity (if any). - /// Picked EntityId will be returned, InvalidEntityId will be returned on failure. + //! Given a point in screen space, return the picked entity (if any). + //! Picked EntityId will be returned, InvalidEntityId will be returned on failure. virtual AZ::EntityId PickEntity(const AzFramework::ScreenPoint& point) = 0; - /// Given a point in screen space, return the terrain position in world space. + //! Given a point in screen space, return the terrain position in world space. virtual AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) = 0; - /// Return the terrain height given a world position in 2d (xy plane). + //! Return the terrain height given a world position in 2d (xy plane). virtual float TerrainHeight(const AZ::Vector2& position) = 0; - /// Given the current view frustum (viewport) return all visible entities. + //! Given the current view frustum (viewport) return all visible entities. virtual void FindVisibleEntities(AZStd::vector& visibleEntities) = 0; - /// Is the user holding a modifier key to move the manipulator space from local to world. + //! Is the user holding a modifier key to move the manipulator space from local to world. virtual bool ShowingWorldSpace() = 0; - /// Return the widget to use as the parent for the viewport context menu. + //! Return the widget to use as the parent for the viewport context menu. virtual QWidget* GetWidgetForViewportContextMenu() = 0; - /// Set the render context for the viewport. + //! Set the render context for the viewport. virtual void BeginWidgetContext() = 0; - /// End the render context for the viewport. - /// Return to previous context before Begin was called. + //! End the render context for the viewport. + //! Return to previous context before Begin was called. virtual void EndWidgetContext() = 0; protected: ~MainEditorViewportInteractionRequests() = default; }; - /// Type to inherit to implement MainEditorViewportInteractionRequests. + //! Type to inherit to implement MainEditorViewportInteractionRequests. using MainEditorViewportInteractionRequestBus = AZ::EBus; - /// Viewport requests for managing the viewport's cursor state. + //! Viewport requests for managing the viewport's cursor state. class ViewportMouseCursorRequests { public: - /// Begins hiding the cursor and locking it in place, to prevent the cursor from escaping the viewport window. + //! Begins hiding the cursor and locking it in place, to prevent the cursor from escaping the viewport window. virtual void BeginCursorCapture() = 0; - /// Restores the cursor and ends locking it in place, allowing it to be moved freely. + //! Restores the cursor and ends locking it in place, allowing it to be moved freely. virtual void EndCursorCapture() = 0; - /// Gets the most recent recorded cursor position in the viewport in screen space coordinates. + //! Gets the most recent recorded cursor position in the viewport in screen space coordinates. virtual AzFramework::ScreenPoint ViewportCursorScreenPosition() = 0; - /// Gets the cursor position recorded prior to the most recent cursor position. - /// Note: The cursor may be captured by the viewport, in which case this may not correspond to the last result - /// from ViewportCursorScreenPosition. This method will always return the correct position to generate a mouse - /// position delta. + //! Gets the cursor position recorded prior to the most recent cursor position. + //! Note: The cursor may be captured by the viewport, in which case this may not correspond to the last result + //! from ViewportCursorScreenPosition. This method will always return the correct position to generate a mouse + //! position delta. virtual AZStd::optional PreviousViewportCursorScreenPosition() = 0; - /// Is mouse over viewport. + //! Is mouse over viewport. virtual bool IsMouseOver() const = 0; protected: ~ViewportMouseCursorRequests() = default; }; - /// Type to inherit to implement MainEditorViewportInteractionRequests. + //! Type to inherit to implement MainEditorViewportInteractionRequests. using ViewportMouseCursorRequestBus = AZ::EBus; - /// A helper to wrap Begin/EndWidgetContext. + //! A helper to wrap Begin/EndWidgetContext. class WidgetContextGuard { public: @@ -294,17 +301,16 @@ namespace AzToolsFramework } private: - int m_viewportId; ///< The viewport id the widget context is being set on. + int m_viewportId; //!< The viewport id the widget context is being set on. }; } // namespace ViewportInteraction - /// Utility function to return EntityContextId. + //! Utility function to return EntityContextId. inline AzFramework::EntityContextId GetEntityContextId() { AzFramework::EntityContextId entityContextId; - EditorEntityContextRequestBus::BroadcastResult( - entityContextId, &EditorEntityContextRequests::GetEditorEntityContextId); + EditorEntityContextRequestBus::BroadcastResult(entityContextId, &EditorEntityContextRequests::GetEditorEntityContextId); return entityContextId; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.cpp index 8d26054562..99808fcd56 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "ViewportTypes.h" @@ -23,26 +23,24 @@ namespace AzToolsFramework { if (auto serializeContext = azrtti_cast(context)) { - serializeContext->Class()-> - Field("KeyboardModifiers", &KeyboardModifiers::m_keyModifiers); + serializeContext->Class()->Field("KeyboardModifiers", &KeyboardModifiers::m_keyModifiers); - serializeContext->Class()-> - Field("MouseButtons", &MouseButtons::m_mouseButtons); + serializeContext->Class()->Field("MouseButtons", &MouseButtons::m_mouseButtons); - serializeContext->Class()-> - Field("CameraId", &InteractionId::m_cameraId)-> - Field("ViewportId", &InteractionId::m_viewportId); + serializeContext->Class() + ->Field("CameraId", &InteractionId::m_cameraId) + ->Field("ViewportId", &InteractionId::m_viewportId); - serializeContext->Class()-> - Field("RayOrigin", &MousePick::m_rayOrigin)-> - Field("RayDirection", &MousePick::m_rayDirection)-> - Field("ScreenCoordinates", &MousePick::m_screenCoordinates); + serializeContext->Class() + ->Field("RayOrigin", &MousePick::m_rayOrigin) + ->Field("RayDirection", &MousePick::m_rayDirection) + ->Field("ScreenCoordinates", &MousePick::m_screenCoordinates); - serializeContext->Class()-> - Field("MousePick", &MouseInteraction::m_mousePick)-> - Field("MouseButtons", &MouseInteraction::m_mouseButtons)-> - Field("InteractionId", &MouseInteraction::m_interactionId)-> - Field("KeyboardModifiers", &MouseInteraction::m_keyboardModifiers); + serializeContext->Class() + ->Field("MousePick", &MouseInteraction::m_mousePick) + ->Field("MouseButtons", &MouseInteraction::m_mouseButtons) + ->Field("InteractionId", &MouseInteraction::m_interactionId) + ->Field("KeyboardModifiers", &MouseInteraction::m_keyboardModifiers); MouseInteractionEvent::Reflect(*serializeContext); } @@ -50,10 +48,10 @@ namespace AzToolsFramework void MouseInteractionEvent::Reflect(AZ::SerializeContext& serializeContext) { - serializeContext.Class()-> - Field("MouseInteraction", &MouseInteractionEvent::m_mouseInteraction)-> - Field("MouseEvent", &MouseInteractionEvent::m_mouseEvent)-> - Field("WheelDelta", &MouseInteractionEvent::m_wheelDelta); + serializeContext.Class() + ->Field("MouseInteraction", &MouseInteractionEvent::m_mouseInteraction) + ->Field("MouseEvent", &MouseInteractionEvent::m_mouseEvent) + ->Field("WheelDelta", &MouseInteractionEvent::m_wheelDelta); } - } -} + } // namespace ViewportInteraction +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.h index d59044e68f..ad045888bc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportTypes.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -27,57 +27,75 @@ namespace AZ namespace AzToolsFramework { - /// Viewport related types that are used when interacting with the viewport. + //! Viewport related types that are used when interacting with the viewport. namespace ViewportInteraction { - /// Flags to represent each modifier key. + //! Flags to represent each modifier key. enum class KeyboardModifier : AZ::u32 { - None = 0, ///< No keyboard modifier. - Alt = 0x01, ///< Alt keyboard modifier. - Shift = 0x02, ///< Shift keyboard modifier. - Ctrl = 0x04, ///< Ctrl keyboard modifier. - Control = Ctrl ///< Alias for Ctrl modifier. + None = 0, //!< No keyboard modifier. + Alt = 0x01, //!< Alt keyboard modifier. + Shift = 0x02, //!< Shift keyboard modifier. + Ctrl = 0x04, //!< Ctrl keyboard modifier. + Control = Ctrl //!< Alias for Ctrl modifier. }; - /// Flags to represent each mouse button. + //! Flags to represent each mouse button. enum class MouseButton : AZ::u32 { - None = 0, ///< No mouse buttons. - Left = 0x01, ///< Left mouse button. - Middle = 0x02, ///< Middle mouse button. - Right = 0x04 ///< Right mouse button. + None = 0, //!< No mouse buttons. + Left = 0x01, //!< Left mouse button. + Middle = 0x02, //!< Middle mouse button. + Right = 0x04 //!< Right mouse button. }; - /// The type of mouse event that occurred. + //! The type of mouse event that occurred. enum class MouseEvent { - Up, ///< Mouse up event, - Down, ///< Mouse down event. - DoubleClick, ///< Mouse double click event. - Wheel, ///< Mouse wheel event. - Move, ///< Mouse move event. + Up, //!< Mouse up event, + Down, //!< Mouse down event. + DoubleClick, //!< Mouse double click event. + Wheel, //!< Mouse wheel event. + Move, //!< Mouse move event. }; - /// Interface over keyboard modifier to query which key is pressed. + //! Interface over keyboard modifier to query which key is pressed. struct KeyboardModifiers { - /// @cond + //! @cond AZ_TYPE_INFO(KeyboardModifiers, "{2635F4DF-E7DC-4919-A97B-9AE35FE086D8}"); KeyboardModifiers() = default; - /// @endcond + //! @endcond - /// Explicit constructor to create a KeyboardModifier struct. - explicit KeyboardModifiers(const AZ::u32 keyModifiers) : m_keyModifiers(keyModifiers) {} + //! Explicit constructor to create a KeyboardModifier struct. + explicit KeyboardModifiers(const AZ::u32 keyModifiers) + : m_keyModifiers(keyModifiers) + { + } + + //! Given the current keyboard modifiers, is the Alt key held. + bool Alt() const + { + return (m_keyModifiers & static_cast(KeyboardModifier::Alt)) != 0; + } - /// Given the current keyboard modifiers, is the Alt key held. - bool Alt() const { return (m_keyModifiers & static_cast(KeyboardModifier::Alt)) != 0; } - /// Given the current keyboard modifiers, is the Shift key held. - bool Shift() const { return (m_keyModifiers & static_cast(KeyboardModifier::Shift)) != 0; } - /// Given the current keyboard modifiers, is the Ctrl key held. - bool Ctrl() const { return (m_keyModifiers & static_cast(KeyboardModifier::Ctrl)) != 0; } - /// Given the current keyboard modifiers, are none being held. - bool None() const { return m_keyModifiers == static_cast(KeyboardModifier::None); } + //! Given the current keyboard modifiers, is the Shift key held. + bool Shift() const + { + return (m_keyModifiers & static_cast(KeyboardModifier::Shift)) != 0; + } + + //! Given the current keyboard modifiers, is the Ctrl key held. + bool Ctrl() const + { + return (m_keyModifiers & static_cast(KeyboardModifier::Ctrl)) != 0; + } + + //! Given the current keyboard modifiers, are none being held. + bool None() const + { + return m_keyModifiers == static_cast(KeyboardModifier::None); + } bool operator==(const KeyboardModifiers& keyboardModifiers) const { @@ -89,132 +107,162 @@ namespace AzToolsFramework return m_keyModifiers != keyboardModifiers.m_keyModifiers; } - AZ::u32 m_keyModifiers = 0; ///< Raw keyboard modifier state. + AZ::u32 m_keyModifiers = 0; //!< Raw keyboard modifier state. }; - /// Interface over mouse buttons to query which button is pressed. + //! Interface over mouse buttons to query which button is pressed. struct MouseButtons { - /// @cond + //! @cond AZ_TYPE_INFO(MouseButtons, "{1D137B5D-73BF-4FD9-BECA-85E6DC3786CB}"); MouseButtons() = default; - /// @endcond - - /// Explicit constructor to create a MouseButton struct. - explicit MouseButtons(const AZ::u32 mouseButtons) : m_mouseButtons(mouseButtons) {} - - /// Given the current mouse state, is the left mouse button held. - bool Left() const { return (m_mouseButtons & static_cast(MouseButton::Left)) != 0; } - /// Given the current mouse state, is the middle mouse button held. - bool Middle() const { return (m_mouseButtons & static_cast(MouseButton::Middle)) != 0; } - /// Given the current mouse state, is the right mouse button held. - bool Right() const { return (m_mouseButtons & static_cast(MouseButton::Right)) != 0; } - /// Given the current mouse state, are no mouse buttons held. - bool None() const { return m_mouseButtons == static_cast(MouseButton::None); } - /// Given the current mouse state, are any mouse buttons held. - bool Any() const { return m_mouseButtons != static_cast(MouseButton::None); } - - AZ::u32 m_mouseButtons = 0; ///< Current mouse button state (flags). + //! @endcond + + //! Explicit constructor to create a MouseButton struct. + explicit MouseButtons(const AZ::u32 mouseButtons) + : m_mouseButtons(mouseButtons) + { + } + + //! Given the current mouse state, is the left mouse button held. + bool Left() const + { + return (m_mouseButtons & static_cast(MouseButton::Left)) != 0; + } + + //! Given the current mouse state, is the middle mouse button held. + bool Middle() const + { + return (m_mouseButtons & static_cast(MouseButton::Middle)) != 0; + } + + //! Given the current mouse state, is the right mouse button held. + bool Right() const + { + return (m_mouseButtons & static_cast(MouseButton::Right)) != 0; + } + + //! Given the current mouse state, are no mouse buttons held. + bool None() const + { + return m_mouseButtons == static_cast(MouseButton::None); + } + + //! Given the current mouse state, are any mouse buttons held. + bool Any() const + { + return m_mouseButtons != static_cast(MouseButton::None); + } + + AZ::u32 m_mouseButtons = 0; //!< Current mouse button state (flags). }; - /// Information relevant when interacting with a particular viewport. + //! Information relevant when interacting with a particular viewport. struct InteractionId { - /// @cond + //! @cond AZ_TYPE_INFO(InteractionId, "{35593FC2-846F-4AAD-8044-4CD84EC84F9A}"); InteractionId() = default; - /// @endcond + //! @endcond InteractionId(AZ::EntityId cameraId, int viewportId) - : m_cameraId(cameraId), m_viewportId(viewportId) {} + : m_cameraId(cameraId) + , m_viewportId(viewportId) + { + } - AZ::EntityId m_cameraId; ///< The entity id of the viewport camera. - int m_viewportId = 0; ///< The id of the viewport being interacted with. + AZ::EntityId m_cameraId; //!< The entity id of the viewport camera. + int m_viewportId = 0; //!< The id of the viewport being interacted with. }; - /// Data representing a mouse pick ray. + //! Data representing a mouse pick ray. struct MousePick { - /// @cond + //! @cond AZ_TYPE_INFO(MousePick, "{A69B9562-FC8C-4DE7-9137-0FF867B1513D}"); MousePick() = default; - /// @endcond + //! @endcond - AZ::Vector3 m_rayOrigin = AZ::Vector3::CreateZero(); ///< World space. - AZ::Vector3 m_rayDirection = AZ::Vector3::CreateZero(); ///< World space - normalized. - AzFramework::ScreenPoint m_screenCoordinates = {}; ///< Screen space. + AZ::Vector3 m_rayOrigin = AZ::Vector3::CreateZero(); //!< World space. + AZ::Vector3 m_rayDirection = AZ::Vector3::CreateZero(); //!< World space - normalized. + AzFramework::ScreenPoint m_screenCoordinates = {}; //!< Screen space. }; - /// State relating to an individual mouse interaction. + //! State relating to an individual mouse interaction. struct MouseInteraction { - /// @cond + //! @cond AZ_TYPE_INFO(MouseInteraction, "{E67357C3-DFE1-40DF-921F-9CBCFE63A68C}"); MouseInteraction() = default; - /// @endcond + //! @endcond - MousePick m_mousePick; ///< The mouse pick ray in world space and screen coordinates in screen space. - MouseButtons m_mouseButtons; ///< The current state of the mouse buttons. + MousePick m_mousePick; //!< The mouse pick ray in world space and screen coordinates in screen space. + MouseButtons m_mouseButtons; //!< The current state of the mouse buttons. InteractionId m_interactionId; /**< The EntityId of the camera this click came from - * and the id of the viewport it originated from. */ - KeyboardModifiers m_keyboardModifiers; ///< The state of the keyboard modifiers (Alt/Ctrl/Shift). + * and the id of the viewport it originated from. */ + KeyboardModifiers m_keyboardModifiers; //!< The state of the keyboard modifiers (Alt/Ctrl/Shift). }; - /// Structure to compose MouseInteraction (mouse state) and - /// MouseEvent (MouseEvent::MouseUp/MouseEvent::DownMove etc.) + //! Structure to compose MouseInteraction (mouse state) and + //! MouseEvent (MouseEvent::MouseUp/MouseEvent::DownMove etc.) struct MouseInteractionEvent { - /// @cond + //! @cond AZ_TYPE_INFO(MouseInteractionEvent, "{67FE0826-DD59-4B5B-BEFE-421E83EA7F31}"); MouseInteractionEvent() = default; - /// @endcond + //! @endcond static void Reflect(AZ::SerializeContext& context); - /// Constructor to create a default MouseInteractionEvent + //! Constructor to create a default MouseInteractionEvent MouseInteractionEvent(MouseInteraction mouseInteraction, const MouseEvent mouseEvent) : m_mouseInteraction(std::move(mouseInteraction)) - , m_mouseEvent(mouseEvent) {} + , m_mouseEvent(mouseEvent) + { + } - /// Special constructor for mouse wheel event. + //! Special constructor for mouse wheel event. MouseInteractionEvent(MouseInteraction mouseInteraction, const float wheelDelta) : m_mouseInteraction(std::move(mouseInteraction)) , m_mouseEvent(MouseEvent::Wheel) - , m_wheelDelta(wheelDelta) {} + , m_wheelDelta(wheelDelta) + { + } - MouseInteraction m_mouseInteraction; ///< Mouse state. - MouseEvent m_mouseEvent; ///< Mouse event. + MouseInteraction m_mouseInteraction; //!< Mouse state. + MouseEvent m_mouseEvent; //!< Mouse event. - /// Special friend function to return the mouse wheel delta (scroll amount) - /// if the event was of type MouseEvent::Wheel. + //! Special friend function to return the mouse wheel delta (scroll amount) + //! if the event was of type MouseEvent::Wheel. friend float MouseWheelDelta(const MouseInteractionEvent& mouseInteractionEvent); private: - float m_wheelDelta = 0.0f; ///< The amount the mouse wheel moved during a mouse wheel event. + float m_wheelDelta = 0.0f; //!< The amount the mouse wheel moved during a mouse wheel event. }; - /// Checked access to mouse wheel delta - ensure event originated from the mouse wheel. + //! Checked access to mouse wheel delta - ensure event originated from the mouse wheel. inline float MouseWheelDelta(const MouseInteractionEvent& mouseInteractionEvent) { - AZ_Assert(mouseInteractionEvent.m_mouseEvent == MouseEvent::Wheel, + AZ_Assert( + mouseInteractionEvent.m_mouseEvent == MouseEvent::Wheel, "Attempting to access mouse wheel delta when mouse interaction event was not mouse wheel"); return mouseInteractionEvent.m_wheelDelta; } - /// Return QPoint from AzFramework::ScreenPoint. + //! Return QPoint from AzFramework::ScreenPoint. inline QPoint QPointFromScreenPoint(const AzFramework::ScreenPoint& screenPoint) { - return {screenPoint.m_x, screenPoint.m_y}; + return { screenPoint.m_x, screenPoint.m_y }; } - /// Return AzFramework::ScreenPoint from QPoint. + //! Return AzFramework::ScreenPoint from QPoint. inline AzFramework::ScreenPoint ScreenPointFromQPoint(const QPoint& qpoint) { - return AzFramework::ScreenPoint{qpoint.x(), qpoint.y()}; + return AzFramework::ScreenPoint{ qpoint.x(), qpoint.y() }; } - /// Map from Qt -> Open 3D Engine buttons.>>>>>>> main + //! Map from Qt -> Open 3D Engine buttons.>>>>>>> main inline AZ::u32 TranslateMouseButtons(const Qt::MouseButtons buttons) { AZ::u32 result = 0; @@ -224,7 +272,7 @@ namespace AzToolsFramework return result; } - /// Map from Qt -> Open 3D Engine modifiers. + //! Map from Qt -> Open 3D Engine modifiers. inline AZ::u32 TranslateKeyboardModifiers(const Qt::KeyboardModifiers modifiers) { AZ::u32 result = 0; @@ -234,19 +282,19 @@ namespace AzToolsFramework return result; } - /// Interface to translate Qt modifiers to Open 3D Engine modifiers. + //! Interface to translate Qt modifiers to Open 3D Engine modifiers. inline KeyboardModifiers BuildKeyboardModifiers(const Qt::KeyboardModifiers modifiers) { return KeyboardModifiers(TranslateKeyboardModifiers(modifiers)); } - /// Interface to translate Qt buttons to Open 3D Engine buttons. + //! Interface to translate Qt buttons to Open 3D Engine buttons. inline MouseButtons BuildMouseButtons(const Qt::MouseButtons buttons) { return MouseButtons(TranslateMouseButtons(buttons)); } - /// Generate mouse buttons from single button enum. + //! Generate mouse buttons from single button enum. inline MouseButtons MouseButtonsFromButton(MouseButton button) { MouseButtons mouseButtons; @@ -254,7 +302,7 @@ namespace AzToolsFramework return mouseButtons; } - /// Reflect all viewport related types. + //! Reflect all viewport related types. void ViewportInteractionReflect(AZ::ReflectContext* context); } // namespace ViewportInteraction } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.cpp index a7f500cc5f..ed776f90ea 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "EditorDefaultSelection.h" @@ -30,8 +30,7 @@ namespace AzToolsFramework ActionOverrideRequestBus::Handler::BusConnect(GetEntityContextId()); ComponentModeFramework::ComponentModeSystemRequestBus::Handler::BusConnect(); - m_manipulatorManager = - AZStd::make_shared(AzToolsFramework::g_mainManipulatorManagerId); + m_manipulatorManager = AZStd::make_shared(AzToolsFramework::g_mainManipulatorManagerId); m_transformComponentSelection = AZStd::make_unique(entityDataCache); } @@ -75,23 +74,18 @@ namespace AzToolsFramework for (const auto& componentModeBuilder : entityAndComponentModeBuilders.m_componentModeBuilders) { m_componentModeCollection.AddComponentMode( - AZ::EntityComponentIdPair( - entityAndComponentModeBuilders.m_entityId, componentModeBuilder.m_componentId), - componentModeBuilder.m_componentType, - componentModeBuilder.m_componentModeBuilder); + AZ::EntityComponentIdPair(entityAndComponentModeBuilders.m_entityId, componentModeBuilder.m_componentId), + componentModeBuilder.m_componentType, componentModeBuilder.m_componentModeBuilder); } } void EditorDefaultSelection::TransitionToComponentMode() { // entering ComponentMode - disable all default actions in the ActionManager - EditorActionRequestBus::Broadcast( - &EditorActionRequests::DisableDefaultActions); + EditorActionRequestBus::Broadcast(&EditorActionRequests::DisableDefaultActions); // attach widget to store ComponentMode specific actions - EditorActionRequestBus::Broadcast( - &EditorActionRequests::AttachOverride, - &PhantomWidget()); + EditorActionRequestBus::Broadcast(&EditorActionRequests::AttachOverride, &PhantomWidget()); if (m_transformComponentSelection) { @@ -103,8 +97,7 @@ namespace AzToolsFramework // refresh button ui ToolsApplicationEvents::Bus::Broadcast( - &ToolsApplicationEvents::Bus::Events::InvalidatePropertyDisplay, - PropertyModificationRefreshLevel::Refresh_EntireTree); + &ToolsApplicationEvents::Bus::Events::InvalidatePropertyDisplay, PropertyModificationRefreshLevel::Refresh_EntireTree); } void EditorDefaultSelection::TransitionFromComponentMode() @@ -117,19 +110,16 @@ namespace AzToolsFramework m_transformComponentSelection->RegisterManipulator(); } - EditorActionRequestBus::Broadcast( - &EditorActionRequests::DetachOverride); + EditorActionRequestBus::Broadcast(&EditorActionRequests::DetachOverride); ClearActionOverrides(); // leaving ComponentMode - enable all default actions in ActionManager - EditorActionRequestBus::Broadcast( - &EditorActionRequests::EnableDefaultActions); + EditorActionRequestBus::Broadcast(&EditorActionRequests::EnableDefaultActions); // refresh button ui ToolsApplicationEvents::Bus::Broadcast( - &ToolsApplicationEvents::Bus::Events::InvalidatePropertyDisplay, - PropertyModificationRefreshLevel::Refresh_EntireTree); + &ToolsApplicationEvents::Bus::Events::InvalidatePropertyDisplay, PropertyModificationRefreshLevel::Refresh_EntireTree); } void EditorDefaultSelection::EndComponentMode() @@ -142,8 +132,7 @@ namespace AzToolsFramework m_componentModeCollection.Refresh(entityComponentIdPair); } - bool EditorDefaultSelection::AddedToComponentMode( - const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid& componentType) + bool EditorDefaultSelection::AddedToComponentMode(const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid& componentType) { return m_componentModeCollection.AddedToComponentMode(entityComponentIdPair, componentType); } @@ -152,10 +141,10 @@ namespace AzToolsFramework { ComponentModeFramework::ComponentModeDelegateRequestBus::EnumerateHandlers( [componentType](ComponentModeFramework::ComponentModeDelegateRequestBus::InterfaceType* componentModeMouseRequests) - { - componentModeMouseRequests->AddComponentModeOfType(componentType); - return true; - }); + { + componentModeMouseRequests->AddComponentModeOfType(componentType); + return true; + }); TransitionToComponentMode(); } @@ -238,8 +227,7 @@ namespace AzToolsFramework } } - bool EditorDefaultSelection::InternalHandleMouseViewportInteraction( - const ViewportInteraction::MouseInteractionEvent& mouseInteraction) + bool EditorDefaultSelection::InternalHandleMouseViewportInteraction(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) { bool enterComponentModeAttempted = false; const bool componentModeBefore = InComponentMode(); @@ -249,15 +237,15 @@ namespace AzToolsFramework { // enumerate all ComponentModeDelegateRequestBus and check if any triggered AddComponentModes ComponentModeFramework::ComponentModeDelegateRequestBus::EnumerateHandlers( - [&mouseInteraction, &enterComponentModeAttempted] - (ComponentModeFramework::ComponentModeDelegateRequestBus::InterfaceType* componentModeMouseRequests) - { - // detect if a double click happened on any Component in the viewport, attempting - // to move it into ComponentMode (note: this is not guaranteed to succeed as an - // incompatible multi-selection may prevent it) - enterComponentModeAttempted = componentModeMouseRequests->DetectEnterComponentModeInteraction(mouseInteraction); - return !enterComponentModeAttempted; - }); + [&mouseInteraction, &enterComponentModeAttempted]( + ComponentModeFramework::ComponentModeDelegateRequestBus::InterfaceType* componentModeMouseRequests) + { + // detect if a double click happened on any Component in the viewport, attempting + // to move it into ComponentMode (note: this is not guaranteed to succeed as an + // incompatible multi-selection may prevent it) + enterComponentModeAttempted = componentModeMouseRequests->DetectEnterComponentModeInteraction(mouseInteraction); + return !enterComponentModeAttempted; + }); // here we know ComponentMode was entered successfully and was not prohibited if (m_componentModeCollection.ModesAdded()) @@ -272,25 +260,24 @@ namespace AzToolsFramework else { ComponentModeFramework::ComponentModeRequestBus::EnumerateHandlers( - [&mouseInteraction, &handled] - (ComponentModeFramework::ComponentModeRequestBus::InterfaceType* componentModeRequest) - { - if (componentModeRequest->HandleMouseInteraction(mouseInteraction)) + [&mouseInteraction, &handled](ComponentModeFramework::ComponentModeRequestBus::InterfaceType* componentModeRequest) { - handled = true; - } + if (componentModeRequest->HandleMouseInteraction(mouseInteraction)) + { + handled = true; + } - return true; - }); + return true; + }); if (!handled) { ComponentModeFramework::ComponentModeDelegateRequestBus::EnumerateHandlers( - [&mouseInteraction] - (ComponentModeFramework::ComponentModeDelegateRequestBus::InterfaceType* componentModeDelegateRequests) - { - return !componentModeDelegateRequests->DetectLeaveComponentModeInteraction(mouseInteraction); - }); + [&mouseInteraction]( + ComponentModeFramework::ComponentModeDelegateRequestBus::InterfaceType* componentModeDelegateRequests) + { + return !componentModeDelegateRequests->DetectLeaveComponentModeInteraction(mouseInteraction); + }); } } @@ -311,8 +298,7 @@ namespace AzToolsFramework } void EditorDefaultSelection::DisplayViewportSelection( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) + const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) { if (m_transformComponentSelection) { @@ -330,8 +316,7 @@ namespace AzToolsFramework } void EditorDefaultSelection::DisplayViewportSelection2d( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) + const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) { if (m_transformComponentSelection) { @@ -355,11 +340,12 @@ namespace AzToolsFramework void EditorDefaultSelection::AddActionOverride(const ActionOverride& actionOverride) { // check if an action with this uri is already added - const auto actionIt = AZStd::find_if(m_actions.begin(), m_actions.end(), + const auto actionIt = AZStd::find_if( + m_actions.begin(), m_actions.end(), [actionOverride](const AZStd::shared_ptr& actionOverrideMapping) - { - return actionOverride.m_uri == actionOverrideMapping->m_uri; - }); + { + return actionOverride.m_uri == actionOverrideMapping->m_uri; + }); // if an action with the same uri is already added, store the callback for this action if (actionIt != m_actions.end()) @@ -381,44 +367,45 @@ namespace AzToolsFramework // set callbacks that should happen when this action is triggered auto index = static_cast(m_actions.size()); - QObject::connect(action.get(), &QAction::triggered, [this, index]() - { - const auto vec = m_actions; // increment ref count of shared_ptr, callback may clear actions - for (auto& callback : vec[index]->m_callbacks) + QObject::connect( + action.get(), &QAction::triggered, + [this, index]() { - callback(); - } - }); + const auto vec = m_actions; // increment ref count of shared_ptr, callback may clear actions + for (auto& callback : vec[index]->m_callbacks) + { + callback(); + } + }); - m_actions.emplace_back( - AZStd::make_shared( - actionOverride.m_uri, AZStd::vector>{ actionOverride.m_callback }, - AZStd::move(action))); + m_actions.emplace_back(AZStd::make_shared( + actionOverride.m_uri, AZStd::vector>{ actionOverride.m_callback }, AZStd::move(action))); // register action with edit menu - EditorMenuRequestBus::Broadcast( - &EditorMenuRequests::AddEditMenuAction, m_actions.back()->m_action.get()); + EditorMenuRequestBus::Broadcast(&EditorMenuRequests::AddEditMenuAction, m_actions.back()->m_action.get()); } } void EditorDefaultSelection::ClearActionOverrides() { - AZStd::for_each(m_actions.begin(), m_actions.end(), + AZStd::for_each( + m_actions.begin(), m_actions.end(), [this](const AZStd::shared_ptr& actionMapping) - { - PhantomWidget().removeAction(actionMapping->m_action.get()); - }); + { + PhantomWidget().removeAction(actionMapping->m_action.get()); + }); m_actions.clear(); } void EditorDefaultSelection::RemoveActionOverride(const AZ::Crc32 actionOverrideUri) { - const auto it = AZStd::find_if(m_actions.begin(), m_actions.end(), + const auto it = AZStd::find_if( + m_actions.begin(), m_actions.end(), [actionOverrideUri](const AZStd::shared_ptr& actionMapping) - { - return actionMapping->m_uri == actionOverrideUri; - }); + { + return actionMapping->m_uri == actionOverrideUri; + }); if (it != m_actions.end()) { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.h index 414e163e2f..d2f2c2fea5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -19,7 +19,7 @@ namespace AzToolsFramework { - /// The default selection/input handler for the editor (includes handling ComponentMode). + //! The default selection/input handler for the editor (includes handling ComponentMode). class EditorDefaultSelection : public ViewportInteraction::InternalViewportSelectionRequests , private ActionOverrideRequestBus::Handler @@ -28,30 +28,26 @@ namespace AzToolsFramework public: AZ_CLASS_ALLOCATOR_DECL - /// @cond + //! @cond explicit EditorDefaultSelection(const EditorVisibleEntityDataCache* entityDataCache); EditorDefaultSelection(const EditorDefaultSelection&) = delete; EditorDefaultSelection& operator=(const EditorDefaultSelection&) = delete; virtual ~EditorDefaultSelection(); - /// @endcond + //! @endcond - /// Override the default widget used to store QActions while in ComponentMode. - /// @note This should not be necessary during normal operation and is provided - /// as a customization point to aid with testing. + //! Override the default widget used to store QActions while in ComponentMode. + //! @note This should not be necessary during normal operation and is provided + //! as a customization point to aid with testing. void SetOverridePhantomWidget(QWidget* phantomOverrideWidget); private: // ViewportInteraction::InternalMouseViewportRequests ... - bool InternalHandleMouseViewportInteraction( - const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override; - bool InternalHandleMouseManipulatorInteraction( - const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override; + bool InternalHandleMouseViewportInteraction(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override; + bool InternalHandleMouseManipulatorInteraction(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override; void DisplayViewportSelection( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) override; + const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override; void DisplayViewportSelection2d( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) override; + const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override; // ActionOverrideRequestBus ... void SetupActionOverrideHandler(QWidget* parent) override; @@ -65,7 +61,10 @@ namespace AzToolsFramework const AZStd::vector& entityAndComponentModeBuilders) override; void AddComponentModes(const ComponentModeFramework::EntityAndComponentModeBuilders& entityAndComponentModeBuilders) override; void EndComponentMode() override; - bool InComponentMode() override { return m_componentModeCollection.InComponentMode(); } + bool InComponentMode() override + { + return m_componentModeCollection.InComponentMode(); + } void Refresh(const AZ::EntityComponentIdPair& entityComponentIdPair) override; bool AddedToComponentMode(const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid& componentType) override; void AddSelectedComponentModesOfType(const AZ::Uuid& componentType) override; @@ -77,41 +76,43 @@ namespace AzToolsFramework bool HasMultipleComponentTypes() override; void RefreshActions() override; - /// Helpers to deal with moving in and out of ComponentMode. + //! Helpers to deal with moving in and out of ComponentMode. void TransitionToComponentMode(); void TransitionFromComponentMode(); - /// Accessor used internally to refer to the phantom widget. - /// This will either be the default widget or the override if non-null. + //! Accessor used internally to refer to the phantom widget. + //! This will either be the default widget or the override if non-null. QWidget& PhantomWidget(); - QWidget m_phantomWidget; ///< The phantom widget responsible for holding QActions while in ComponentMode. - QWidget* m_phantomOverrideWidget = nullptr; ///< It's possible to override the phantom widget in special circumstances (eg testing). - ComponentModeFramework::ComponentModeCollection m_componentModeCollection; ///< Handles all active ComponentMode types. - AZStd::unique_ptr m_transformComponentSelection = nullptr; ///< Viewport selection (responsible for - ///< manipulators and transform modifications). - const EditorVisibleEntityDataCache* m_entityDataCache = nullptr; ///< Reference to cached visible EntityData. + QWidget m_phantomWidget; //!< The phantom widget responsible for holding QActions while in ComponentMode. + QWidget* m_phantomOverrideWidget = nullptr; //!< It's possible to override the phantom widget in special circumstances (eg testing). + ComponentModeFramework::ComponentModeCollection m_componentModeCollection; //!< Handles all active ComponentMode types. + AZStd::unique_ptr m_transformComponentSelection = + nullptr; //!< Viewport selection (responsible for + //!< manipulators and transform modifications). + const EditorVisibleEntityDataCache* m_entityDataCache = nullptr; //!< Reference to cached visible EntityData. - /// Mapping between passed ActionOverride (AddActionOverride) and allocated QAction. + //! Mapping between passed ActionOverride (AddActionOverride) and allocated QAction. struct ActionOverrideMapping { ActionOverrideMapping( - const AZ::Crc32 uri, const AZStd::vector>& callbacks, - AZStd::unique_ptr action) + const AZ::Crc32 uri, const AZStd::vector>& callbacks, AZStd::unique_ptr action) : m_uri(uri) , m_callbacks(callbacks) - , m_action(AZStd::move(action)) {} - - AZ::Crc32 m_uri; ///< Unique identifier for the Action. (In the form 'com.amazon.action.---"). - AZStd::vector> m_callbacks; ///< Callbacks associated with this Action (note: with multi-selections there - ///< will be a callback per Entity/Component). - AZStd::unique_ptr m_action; ///< The QAction associated with the overrideWidget for all ComponentMode actions. + , m_action(AZStd::move(action)) + { + } + + AZ::Crc32 m_uri; //!< Unique identifier for the Action. (In the form 'com.amazon.action.---"). + AZStd::vector> m_callbacks; //!< Callbacks associated with this Action (note: with multi-selections + //!< there will be a callback per Entity/Component). + AZStd::unique_ptr m_action; //!< The QAction associated with the overrideWidget for all ComponentMode actions. }; - AZStd::vector> m_actions; ///< Currently bound actions (corresponding to those set - ///< on the override widget). + AZStd::vector> m_actions; //!< Currently bound actions (corresponding to those set + //!< on the override widget). - AZStd::shared_ptr m_manipulatorManager; ///< The default manipulator manager. - ViewportInteraction::MouseInteraction m_currentInteraction; ///< Current mouse interaction to be used for drawing manipulators. + AZStd::shared_ptr m_manipulatorManager; //!< The default manipulator manager. + ViewportInteraction::MouseInteraction m_currentInteraction; //!< Current mouse interaction to be used for drawing manipulators. }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.cpp index 31da01fadc..6080f6f7ae 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "EditorHelpers.h" @@ -16,21 +16,33 @@ #include #include #include +#include #include #include #include -#include #include -#include +#include AZ_CVAR( - bool, ed_visibility_showAggregateEntitySelectionBounds, false, nullptr, AZ::ConsoleFunctorFlags::Null, + bool, + ed_visibility_showAggregateEntitySelectionBounds, + false, + nullptr, + AZ::ConsoleFunctorFlags::Null, "Display the aggregate selection bounds for a given entity (the union of all component Aabbs)"); AZ_CVAR( - bool, ed_visibility_showAggregateEntityTransformedLocalBounds, false, nullptr, AZ::ConsoleFunctorFlags::Null, + bool, + ed_visibility_showAggregateEntityTransformedLocalBounds, + false, + nullptr, + AZ::ConsoleFunctorFlags::Null, "Display the aggregate transformed local bounds for a given entity (the union of all local component Aabbs)"); AZ_CVAR( - bool, ed_visibility_showAggregateEntityWorldBounds, false, nullptr, AZ::ConsoleFunctorFlags::Null, + bool, + ed_visibility_showAggregateEntityWorldBounds, + false, + nullptr, + AZ::ConsoleFunctorFlags::Null, "Display the aggregate world bounds for a given entity (the union of all world component Aabbs)"); namespace AzToolsFramework @@ -48,8 +60,7 @@ namespace AzToolsFramework static bool HelpersVisible() { bool helpersVisible = false; - EditorRequestBus::BroadcastResult( - helpersVisible, &EditorRequests::DisplayHelpersVisible); + EditorRequestBus::BroadcastResult(helpersVisible, &EditorRequests::DisplayHelpersVisible); return helpersVisible; } @@ -59,25 +70,23 @@ namespace AzToolsFramework { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); - return s_iconMinScale + (s_iconMaxScale - s_iconMinScale) * + return s_iconMinScale + + (s_iconMaxScale - s_iconMinScale) * (1.0f - AZ::GetClamp(AZ::GetMax(0.0f, sqrtf(distSq) - s_iconCloseDist) / s_iconFarDist, 0.0f, 1.0f)); } static void DisplayComponents( - const AZ::EntityId entityId, const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) + const AZ::EntityId entityId, const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); const AZ::Entity* entity = AZ::Interface::Get()->FindEntity(entityId); AzFramework::EntityDebugDisplayEventBus::Event( - entityId, &AzFramework::EntityDebugDisplayEvents::DisplayEntityViewport, - viewportInfo, debugDisplay); + entityId, &AzFramework::EntityDebugDisplayEvents::DisplayEntityViewport, viewportInfo, debugDisplay); if (ed_visibility_showAggregateEntitySelectionBounds) { - if (const AZ::Aabb aabb = AzToolsFramework::CalculateEditorEntitySelectionBounds(entityId, viewportInfo); - aabb.IsValid()) + if (const AZ::Aabb aabb = AzToolsFramework::CalculateEditorEntitySelectionBounds(entityId, viewportInfo); aabb.IsValid()) { debugDisplay.SetColor(AZ::Colors::Orange); debugDisplay.DrawWireBox(aabb.GetMin(), aabb.GetMax()); @@ -107,8 +116,7 @@ namespace AzToolsFramework } AZ::EntityId EditorHelpers::HandleMouseInteraction( - const AzFramework::CameraState& cameraState, - const ViewportInteraction::MouseInteractionEvent& mouseInteraction) + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteractionEvent& mouseInteraction) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -127,8 +135,7 @@ namespace AzToolsFramework { const AZ::EntityId entityId = m_entityDataCache->GetVisibleEntityId(entityCacheIndex); - if ( m_entityDataCache->IsVisibleEntityLocked(entityCacheIndex) - || !m_entityDataCache->IsVisibleEntityVisible(entityCacheIndex)) + if (m_entityDataCache->IsVisibleEntityLocked(entityCacheIndex) || !m_entityDataCache->IsVisibleEntityVisible(entityCacheIndex)) { continue; } @@ -148,10 +155,8 @@ namespace AzToolsFramework const auto iconRange = static_cast(GetIconScale(distSqFromCamera) * s_iconSize * 0.5f); const auto screenCoords = mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates; - if ( screenCoords.m_x >= screenPosition.m_x - iconRange - && screenCoords.m_x <= screenPosition.m_x + iconRange - && screenCoords.m_y >= screenPosition.m_y - iconRange - && screenCoords.m_y <= screenPosition.m_y + iconRange) + if (screenCoords.m_x >= screenPosition.m_x - iconRange && screenCoords.m_x <= screenPosition.m_x + iconRange && + screenCoords.m_y >= screenPosition.m_y - iconRange && screenCoords.m_y <= screenPosition.m_y + iconRange) { entityIdUnderCursor = entityId; break; @@ -161,16 +166,13 @@ namespace AzToolsFramework using AzFramework::ViewportInfo; // check if components provide an aabb - if (const AZ::Aabb aabb = CalculateEditorEntitySelectionBounds(entityId, ViewportInfo{viewportId}); - aabb.IsValid()) + if (const AZ::Aabb aabb = CalculateEditorEntitySelectionBounds(entityId, ViewportInfo{ viewportId }); aabb.IsValid()) { // coarse grain check if (AabbIntersectMouseRay(mouseInteraction.m_mouseInteraction, aabb)) { // if success, pick against specific component - if (PickEntity( - entityId, mouseInteraction.m_mouseInteraction, - closestDistance, viewportId)) + if (PickEntity(entityId, mouseInteraction.m_mouseInteraction, closestDistance, viewportId)) { entityIdUnderCursor = entityId; } @@ -182,7 +184,8 @@ namespace AzToolsFramework } void EditorHelpers::DisplayHelpers( - const AzFramework::ViewportInfo& viewportInfo, const AzFramework::CameraState& cameraState, + const AzFramework::ViewportInfo& viewportInfo, + const AzFramework::CameraState& cameraState, AzFramework::DebugDisplayRequests& debugDisplay, const AZStd::function& showIconCheck) { @@ -202,8 +205,8 @@ namespace AzToolsFramework // notify components to display DisplayComponents(entityId, viewportInfo, debugDisplay); - if ( m_entityDataCache->IsVisibleEntityIconHidden(entityCacheIndex) - || (m_entityDataCache->IsVisibleEntitySelected(entityCacheIndex) && !showIconCheck(entityId))) + if (m_entityDataCache->IsVisibleEntityIconHidden(entityCacheIndex) || + (m_entityDataCache->IsVisibleEntitySelected(entityCacheIndex) && !showIconCheck(entityId))) { continue; } @@ -219,7 +222,8 @@ namespace AzToolsFramework const float iconSize = s_iconSize * iconScale; using ComponentEntityAccentType = Components::EditorSelectionAccentSystemComponent::ComponentEntityAccentType; - const AZ::Color iconHighlight = [this, entityCacheIndex]() { + const AZ::Color iconHighlight = [this, entityCacheIndex]() + { if (m_entityDataCache->IsVisibleEntityLocked(entityCacheIndex)) { return AZ::Color(AZ::u8(100), AZ::u8(100), AZ::u8(100), AZ::u8(255)); @@ -233,14 +237,9 @@ namespace AzToolsFramework return AZ::Color(1.0f, 1.0f, 1.0f, 1.0f); }(); - EditorViewportIconDisplay::Get()->DrawIcon({ - viewportInfo.m_viewportId, - iconTextureId, - iconHighlight, - entityPosition, - EditorViewportIconDisplayInterface::CoordinateSpace::WorldSpace, - AZ::Vector2{iconSize, iconSize} - }); + EditorViewportIconDisplay::Get()->DrawIcon({ viewportInfo.m_viewportId, iconTextureId, iconHighlight, entityPosition, + EditorViewportIconDisplayInterface::CoordinateSpace::WorldSpace, + AZ::Vector2{ iconSize, iconSize } }); } } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.h index e36203e31d..926cadee34 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -21,7 +21,7 @@ namespace AzFramework class DebugDisplayRequests; struct ViewportInfo; struct CameraState; -} +} // namespace AzFramework namespace AzToolsFramework { @@ -32,37 +32,39 @@ namespace AzToolsFramework struct MouseInteractionEvent; } - /// EditorHelpers are the visualizations that appear for entities - /// when 'Display Helpers' is toggled on inside the editor. - /// These include but are not limited to entity icons and shape visualizations. + //! EditorHelpers are the visualizations that appear for entities + //! when 'Display Helpers' is toggled on inside the editor. + //! These include but are not limited to entity icons and shape visualizations. class EditorHelpers { public: AZ_CLASS_ALLOCATOR_DECL - /// An EditorVisibleEntityDataCache must be passed to EditorHelpers to allow it to - /// efficiently read entity data without resorting to EBus calls. + //! An EditorVisibleEntityDataCache must be passed to EditorHelpers to allow it to + //! efficiently read entity data without resorting to EBus calls. explicit EditorHelpers(const EditorVisibleEntityDataCache* entityDataCache) - : m_entityDataCache(entityDataCache) {} + : m_entityDataCache(entityDataCache) + { + } EditorHelpers(const EditorHelpers&) = delete; EditorHelpers& operator=(const EditorHelpers&) = delete; ~EditorHelpers() = default; - /// Handle any mouse interaction with the EditorHelpers. - /// Used to check if a particular entity was selected. + //! Handle any mouse interaction with the EditorHelpers. + //! Used to check if a particular entity was selected. AZ::EntityId HandleMouseInteraction( - const AzFramework::CameraState& cameraState, - const ViewportInteraction::MouseInteractionEvent& mouseInteraction); + const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteractionEvent& mouseInteraction); - /// Do the drawing responsible for the EditorHelpers. - /// @param showIconCheck Provide a custom callback to filter certain entities from - /// displaying an icon under certain conditions. + //! Do the drawing responsible for the EditorHelpers. + //! @param showIconCheck Provide a custom callback to filter certain entities from + //! displaying an icon under certain conditions. void DisplayHelpers( - const AzFramework::ViewportInfo& viewportInfo, const AzFramework::CameraState& cameraState, + const AzFramework::ViewportInfo& viewportInfo, + const AzFramework::CameraState& cameraState, AzFramework::DebugDisplayRequests& debugDisplay, const AZStd::function& showIconCheck); private: - const EditorVisibleEntityDataCache* m_entityDataCache = nullptr; ///< Entity Data queried by the EditorHelpers. + const EditorVisibleEntityDataCache* m_entityDataCache = nullptr; //!< Entity Data queried by the EditorHelpers. }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorInteractionSystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorInteractionSystemComponent.cpp index 12f10e9784..578e113aaf 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorInteractionSystemComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorInteractionSystemComponent.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "EditorInteractionSystemComponent.h" @@ -45,8 +45,7 @@ namespace AzToolsFramework return m_interactionRequests->InternalHandleMouseManipulatorInteraction(mouseInteraction); } - void EditorInteractionSystemComponent::SetHandler( - const ViewportSelectionRequestsBuilderFn& interactionRequestsBuilder) + void EditorInteractionSystemComponent::SetHandler(const ViewportSelectionRequestsBuilderFn& interactionRequestsBuilder) { // when setting a handler, make sure we're connected to the ViewportDebugDisplayEventBus so we // can forward calls to the specific type implementing ViewportSelectionRequests @@ -57,32 +56,30 @@ namespace AzToolsFramework m_entityDataCache = AZStd::make_unique(); - m_interactionRequests.reset(); // BusConnect/Disconnect in constructor/destructor, + m_interactionRequests.reset(); // BusConnect/Disconnect in constructor/destructor, // so have to reset before assigning the new one m_interactionRequests = interactionRequestsBuilder(m_entityDataCache.get()); } void EditorInteractionSystemComponent::SetDefaultHandler() { - SetHandler([](const EditorVisibleEntityDataCache* entityDataCache) - { - return AZStd::make_unique(entityDataCache); - }); + SetHandler( + [](const EditorVisibleEntityDataCache* entityDataCache) + { + return AZStd::make_unique(entityDataCache); + }); } void EditorInteractionSystemComponent::Reflect(AZ::ReflectContext* context) { if (auto serializeContext = azrtti_cast(context)) { - serializeContext->Class() - ->Version(0) - ; + serializeContext->Class()->Version(0); } } void EditorInteractionSystemComponent::DisplayViewport( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) + const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -93,8 +90,7 @@ namespace AzToolsFramework } void EditorInteractionSystemComponent::DisplayViewport2d( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) + const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) { m_interactionRequests->DisplayViewportSelection2d(viewportInfo, debugDisplay); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorInteractionSystemComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorInteractionSystemComponent.h index 2205add970..8fba5c923d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorInteractionSystemComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorInteractionSystemComponent.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -18,9 +18,9 @@ namespace AzToolsFramework { - /// System Component to wrap active input handler. - /// EditorInteractionSystemComponent is notified of viewport mouse events from RenderViewport - /// and forwards them to a concrete implementation of ViewportSelectionRequests. + //! System Component to wrap active input handler. + //! EditorInteractionSystemComponent is notified of viewport mouse events from RenderViewport + //! and forwards them to a concrete implementation of ViewportSelectionRequests. class EditorInteractionSystemComponent : public AZ::Component , private EditorInteractionSystemViewportSelectionRequestBus::Handler @@ -37,18 +37,12 @@ namespace AzToolsFramework void SetDefaultHandler() override; // EditorInteractionSystemViewportSelectionRequestBus ... - bool InternalHandleMouseViewportInteraction( - const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override; - bool InternalHandleMouseManipulatorInteraction( - const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override; + bool InternalHandleMouseViewportInteraction(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override; + bool InternalHandleMouseManipulatorInteraction(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override; // AzFramework::ViewportDebugDisplayEventBus - void DisplayViewport( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) override; - void DisplayViewport2d( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) override; + void DisplayViewport(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override; + void DisplayViewport2d(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override; private: // AZ::Component @@ -58,11 +52,11 @@ namespace AzToolsFramework // EditorEventsBus void NotifyCentralWidgetInitialized() override; - AZStd::unique_ptr m_entityDataCache = nullptr; ///< Visible EntityData cache to be used by concrete - ///< instantiations of ViewportSelectionRequests. + AZStd::unique_ptr m_entityDataCache = nullptr; //!< Visible EntityData cache to be used by concrete + //!< instantiations of ViewportSelectionRequests. - AZStd::unique_ptr m_interactionRequests; ///< Hold a concrete implementation of - ///< ViewportSelectionRequests to handle viewport - ///< input and drawing for the Editor. + AZStd::unique_ptr m_interactionRequests; //!< Hold a concrete implementation of + //!< ViewportSelectionRequests to handle viewport + //!< input and drawing for the Editor. }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h index 09135069d8..184fa29aa0 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -22,10 +22,9 @@ namespace AzToolsFramework { class EditorVisibleEntityDataCache; - /// Bus to handle all mouse events originating from the viewport. - /// Coordinated by the EditorInteractionSystemComponent - class EditorInteractionSystemViewportSelectionRequests - : public AZ::EBusTraits + //! Bus to handle all mouse events originating from the viewport. + //! Coordinated by the EditorInteractionSystemComponent + class EditorInteractionSystemViewportSelectionRequests : public AZ::EBusTraits { public: using BusIdType = AzFramework::EntityContextId; @@ -36,32 +35,31 @@ namespace AzToolsFramework ~EditorInteractionSystemViewportSelectionRequests() = default; }; - /// Alias for factory function to create a new type implementing the ViewportSelectionRequests interface. + //! Alias for factory function to create a new type implementing the ViewportSelectionRequests interface. using ViewportSelectionRequestsBuilderFn = AZStd::function(const EditorVisibleEntityDataCache*)>; - /// Interface for system component implementing the ViewportSelectionRequests interface. - /// This interface also includes a setter to set a custom handler also implementing - /// the ViewportSelectionRequests interface to customize editor behavior. - class EditorInteractionSystemViewportSelection - : public ViewportInteraction::InternalViewportSelectionRequests + //! Interface for system component implementing the ViewportSelectionRequests interface. + //! This interface also includes a setter to set a custom handler also implementing + //! the ViewportSelectionRequests interface to customize editor behavior. + class EditorInteractionSystemViewportSelection : public ViewportInteraction::InternalViewportSelectionRequests { public: - /// \ref SetHandler takes a factory function to create a new type implementing - /// the ViewportSelectionRequests interface. - /// It provides a handler implementing ViewportSelectionRequests to handle all - /// viewport mouse input and drawing. + //! \ref SetHandler takes a factory function to create a new type implementing + //! the ViewportSelectionRequests interface. + //! It provides a handler implementing ViewportSelectionRequests to handle all + //! viewport mouse input and drawing. virtual void SetHandler(const ViewportSelectionRequestsBuilderFn& interactionRequestsBuilder) = 0; - /// \ref SetDefaultHandler is a utility function to set the - /// default editor handler (currently \ref EditorDefaultSelection). - /// This is useful to call after setting another mode and then wishing - /// to return to normal operation of the editor. + //! \ref SetDefaultHandler is a utility function to set the + //! default editor handler (currently \ref EditorDefaultSelection). + //! This is useful to call after setting another mode and then wishing + //! to return to normal operation of the editor. virtual void SetDefaultHandler() = 0; }; - /// Type to inherit to implement EditorInteractionSystemViewportSelection. - /// @note Called by viewport events (RenderViewport) and then handled by concrete - /// implementation of InternalViewportSelectionRequests. + //! Type to inherit to implement EditorInteractionSystemViewportSelection. + //! @note Called by viewport events (RenderViewport) and then handled by concrete + //! implementation of InternalViewportSelectionRequests. using EditorInteractionSystemViewportSelectionRequestBus = AZ::EBus; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorPickEntitySelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorPickEntitySelection.cpp index 1be8ee927b..e026c1f9e0 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorPickEntitySelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorPickEntitySelection.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "EditorPickEntitySelection.h" @@ -19,9 +19,8 @@ namespace AzToolsFramework { AZ_CLASS_ALLOCATOR_IMPL(EditorPickEntitySelection, AZ::SystemAllocator, 0) - EditorPickEntitySelection::EditorPickEntitySelection( - const EditorVisibleEntityDataCache* entityDataCache) - : m_editorHelpers(AZStd::make_unique(entityDataCache)) + EditorPickEntitySelection::EditorPickEntitySelection(const EditorVisibleEntityDataCache* entityDataCache) + : m_editorHelpers(AZStd::make_unique(entityDataCache)) { } @@ -29,8 +28,7 @@ namespace AzToolsFramework { if (m_hoveredEntityId.IsValid()) { - ToolsApplicationRequestBus::Broadcast( - &ToolsApplicationRequests::SetEntityHighlighted, m_hoveredEntityId, false); + ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetEntityHighlighted, m_hoveredEntityId, false); } } @@ -41,8 +39,7 @@ namespace AzToolsFramework // highlighted - hoveredEntityId is an in/out param that is updated based on the change in // entityIdUnderCursor. static void HandleAccents( - const AZ::EntityId entityIdUnderCursor, AZ::EntityId& hoveredEntityId, - const ViewportInteraction::MouseButtons mouseButtons) + const AZ::EntityId entityIdUnderCursor, AZ::EntityId& hoveredEntityId, const ViewportInteraction::MouseButtons mouseButtons) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -55,8 +52,7 @@ namespace AzToolsFramework { if (hoveredEntityId.IsValid()) { - ToolsApplicationRequestBus::Broadcast( - &ToolsApplicationRequests::SetEntityHighlighted, hoveredEntityId, false); + ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetEntityHighlighted, hoveredEntityId, false); hoveredEntityId.SetInvalid(); } @@ -68,8 +64,7 @@ namespace AzToolsFramework { if (entityIdUnderCursor.IsValid() && entityIdUnderCursor != hoveredEntityId) { - ToolsApplicationRequestBus::Broadcast( - &ToolsApplicationRequests::SetEntityHighlighted, entityIdUnderCursor, true); + ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetEntityHighlighted, entityIdUnderCursor, true); hoveredEntityId = entityIdUnderCursor; } @@ -93,8 +88,7 @@ namespace AzToolsFramework if (m_cachedEntityIdUnderCursor.IsValid()) { // if we clicked on a valid entity id, actually try to set it - EditorPickModeRequestBus::Broadcast( - &EditorPickModeRequests::PickModeSelectEntity, m_cachedEntityIdUnderCursor); + EditorPickModeRequestBus::Broadcast(&EditorPickModeRequests::PickModeSelectEntity, m_cachedEntityIdUnderCursor); } // after a click, always stop pick mode, whether we set an entity or not @@ -105,16 +99,18 @@ namespace AzToolsFramework } void EditorPickEntitySelection::DisplayViewportSelection( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) + const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) { const AzFramework::CameraState cameraState = GetCameraState(viewportInfo.m_viewportId); m_editorHelpers->DisplayHelpers( - viewportInfo, cameraState, debugDisplay, [](AZ::EntityId){ return true; }); + viewportInfo, cameraState, debugDisplay, + [](AZ::EntityId) + { + return true; + }); HandleAccents( - m_cachedEntityIdUnderCursor, m_hoveredEntityId, - ViewportInteraction::BuildMouseButtons(QGuiApplication::mouseButtons())); + m_cachedEntityIdUnderCursor, m_hoveredEntityId, ViewportInteraction::BuildMouseButtons(QGuiApplication::mouseButtons())); } } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorPickEntitySelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorPickEntitySelection.h index 07aafe2607..2c956e1534 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorPickEntitySelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorPickEntitySelection.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -17,10 +17,9 @@ namespace AzToolsFramework { - /// Viewport interaction that will handle assigning an entity in the viewport to - /// an entity field in the entity inspector. - class EditorPickEntitySelection - : public ViewportInteraction::InternalViewportSelectionRequests + //! Viewport interaction that will handle assigning an entity in the viewport to + //! an entity field in the entity inspector. + class EditorPickEntitySelection : public ViewportInteraction::InternalViewportSelectionRequests { public: AZ_CLASS_ALLOCATOR_DECL @@ -30,15 +29,12 @@ namespace AzToolsFramework private: // ViewportInteraction::InternalViewportSelectionRequests ... - bool InternalHandleMouseViewportInteraction( - const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override; + bool InternalHandleMouseViewportInteraction(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override; void DisplayViewportSelection( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) override; + const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override; - AZStd::unique_ptr m_editorHelpers; ///< Editor visualization of entities (icons, shapes, debug visuals etc). - - AZ::EntityId m_hoveredEntityId; ///< What EntityId is the mouse currently hovering over (if any). - AZ::EntityId m_cachedEntityIdUnderCursor; ///< Store the EntityId on each mouse move for use in Display. + AZStd::unique_ptr m_editorHelpers; //!< Editor visualization of entities (icons, shapes, debug visuals etc). + AZ::EntityId m_hoveredEntityId; //!< What EntityId is the mouse currently hovering over (if any). + AZ::EntityId m_cachedEntityIdUnderCursor; //!< Store the EntityId on each mouse move for use in Display. }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.cpp index d0143c5517..7856c159ab 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.cpp @@ -1,38 +1,36 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "EditorSelectionUtil.h" -#include +#include #include +#include #include -#include #include #include #include namespace AzToolsFramework { - /// Default ray length for picking in the viewport. + // default ray length for picking in the viewport static const float s_pickRayLength = 1000.0f; - AZ::Vector3 CalculateCenterOffset( - const AZ::EntityId entityId, const EditorTransformComponentSelectionRequests::Pivot pivot) + AZ::Vector3 CalculateCenterOffset(const AZ::EntityId entityId, const EditorTransformComponentSelectionRequests::Pivot pivot) { if (Centered(pivot)) { const AZ::Entity* entity = AZ::Interface::Get()->FindEntity(entityId); - if (const AZ::Aabb localBound = AzFramework::CalculateEntityLocalBoundsUnion(entity); - localBound.IsValid()) + if (const AZ::Aabb localBound = AzFramework::CalculateEntityLocalBoundsUnion(entity); localBound.IsValid()) { return localBound.GetCenter(); } @@ -41,76 +39,71 @@ namespace AzToolsFramework return AZ::Vector3::CreateZero(); } - float CalculateScreenToWorldMultiplier( - const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState) + float CalculateScreenToWorldMultiplier(const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState) { const float apparentDistance = 10.0f; // compute the distance from the camera, projected onto the camera's forward direction // note: this keeps the scale value the same when positions are at the edge of the screen - const float projectedCameraDistance = - std::abs((cameraState.m_position - worldPosition).Dot(cameraState.m_forward)); + const float projectedCameraDistance = std::abs((cameraState.m_position - worldPosition).Dot(cameraState.m_forward)); // author sizes of bounds/manipulators as they would appear // in perspective 10 meters from the camera. return AZ::GetMax(projectedCameraDistance, cameraState.m_nearClip) / apparentDistance; } - AzFramework::ScreenPoint GetScreenPosition(const int viewportId, const AZ::Vector3& worldTranslation) + AzFramework::ScreenPoint GetScreenPosition(const int viewportId, const AZ::Vector3& worldTranslation) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); auto screenPosition = AzFramework::ScreenPoint(0, 0); ViewportInteraction::ViewportInteractionRequestBus::EventResult( - screenPosition, viewportId, - &ViewportInteraction::ViewportInteractionRequestBus::Events::ViewportWorldToScreen, + screenPosition, viewportId, &ViewportInteraction::ViewportInteractionRequestBus::Events::ViewportWorldToScreen, worldTranslation); return screenPosition; } - bool AabbIntersectMouseRay( - const ViewportInteraction::MouseInteraction& mouseInteraction, const AZ::Aabb& aabb) + bool AabbIntersectMouseRay(const ViewportInteraction::MouseInteraction& mouseInteraction, const AZ::Aabb& aabb) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); - const AZ::Vector3 rayScaledDir = - mouseInteraction.m_mousePick.m_rayDirection * s_pickRayLength; + const AZ::Vector3 rayScaledDir = mouseInteraction.m_mousePick.m_rayDirection * s_pickRayLength; AZ::Vector3 startNormal; float t, end; return AZ::Intersect::IntersectRayAABB( - mouseInteraction.m_mousePick.m_rayOrigin, rayScaledDir, - rayScaledDir.GetReciprocal(), aabb, t, end, startNormal) > 0; + mouseInteraction.m_mousePick.m_rayOrigin, rayScaledDir, rayScaledDir.GetReciprocal(), aabb, t, end, startNormal) > 0; } bool PickEntity( - const AZ::EntityId entityId, const ViewportInteraction::MouseInteraction& mouseInteraction, - float& closestDistance, const int viewportId) + const AZ::EntityId entityId, + const ViewportInteraction::MouseInteraction& mouseInteraction, + float& closestDistance, + const int viewportId) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Entity); bool entityPicked = false; EditorComponentSelectionRequestsBus::EnumerateHandlersId( - entityId, [mouseInteraction, &entityPicked, &closestDistance, viewportId] - (EditorComponentSelectionRequests* handler) -> bool - { - if (handler->SupportsEditorRayIntersect()) + entityId, + [mouseInteraction, &entityPicked, &closestDistance, viewportId](EditorComponentSelectionRequests* handler) -> bool { - float distance = std::numeric_limits::max(); - const bool intersection = handler->EditorSelectionIntersectRayViewport( - { viewportId }, mouseInteraction.m_mousePick.m_rayOrigin, - mouseInteraction.m_mousePick.m_rayDirection, distance); - - if (intersection && distance < closestDistance) + if (handler->SupportsEditorRayIntersect()) { - entityPicked = true; - closestDistance = distance; + float distance = std::numeric_limits::max(); + const bool intersection = handler->EditorSelectionIntersectRayViewport( + { viewportId }, mouseInteraction.m_mousePick.m_rayOrigin, mouseInteraction.m_mousePick.m_rayDirection, distance); + + if (intersection && distance < closestDistance) + { + entityPicked = true; + closestDistance = distance; + } } - } - return true; // iterate over all handlers - }); + return true; // iterate over all handlers + }); return entityPicked; } @@ -119,9 +112,8 @@ namespace AzToolsFramework { AzFramework::CameraState cameraState; ViewportInteraction::ViewportInteractionRequestBus::EventResult( - cameraState, viewportId, - &ViewportInteraction::ViewportInteractionRequestBus::Events::GetCameraState); - + cameraState, viewportId, &ViewportInteraction::ViewportInteractionRequestBus::Events::GetCameraState); + return cameraState; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.h index e904277078..a7c6368d65 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -30,56 +30,53 @@ namespace AzFramework namespace AzToolsFramework { - /// Is the pivot at the center of the object (middle of extents) or at the - /// exported authored object root position. + //! Is the pivot at the center of the object (middle of extents) or at the + //! exported authored object root position. inline bool Centered(const EditorTransformComponentSelectionRequests::Pivot pivot) { return pivot == EditorTransformComponentSelectionRequests::Pivot::Center; } - /// Return offset from object pivot to center if center is true, otherwise Vector3::Zero. + //! Return offset from object pivot to center if center is true, otherwise Vector3::Zero. AZ::Vector3 CalculateCenterOffset(AZ::EntityId entityId, EditorTransformComponentSelectionRequests::Pivot pivot); - /// Calculate scale factor based on distance from camera - float CalculateScreenToWorldMultiplier( - const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState); + //! Calculate scale factor based on distance from camera + float CalculateScreenToWorldMultiplier(const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState); - /// Map from world space to screen space. - AzFramework::ScreenPoint GetScreenPosition(int viewportId, const AZ::Vector3& worldTranslation); + //! Map from world space to screen space. + AzFramework::ScreenPoint GetScreenPosition(int viewportId, const AZ::Vector3& worldTranslation); - /// Given a mouse interaction, determine if the pick ray from its position - /// in screen space intersected an aabb in world space. - bool AabbIntersectMouseRay( - const ViewportInteraction::MouseInteraction& mouseInteraction, const AZ::Aabb& aabb); + //! Given a mouse interaction, determine if the pick ray from its position + //! in screen space intersected an aabb in world space. + bool AabbIntersectMouseRay(const ViewportInteraction::MouseInteraction& mouseInteraction, const AZ::Aabb& aabb); - /// Return if a mouse interaction (pick ray) did intersect the tested EntityId. + //! Return if a mouse interaction (pick ray) did intersect the tested EntityId. bool PickEntity( - AZ::EntityId entityId, const ViewportInteraction::MouseInteraction& mouseInteraction, - float& closestDistance, int viewportId); + AZ::EntityId entityId, const ViewportInteraction::MouseInteraction& mouseInteraction, float& closestDistance, int viewportId); - /// Wrapper for EBus call to return the CameraState for a given viewport. + //! Wrapper for EBus call to return the CameraState for a given viewport. AzFramework::CameraState GetCameraState(int viewportId); - /// Wrapper for EBus call to return the DPI scaling for a given viewport. - float GetScreenDisplayScaling(const int viewportId); + //! Wrapper for EBus call to return the DPI scaling for a given viewport. + float GetScreenDisplayScaling(int viewportId); - /// A utility to return the center of several points. - /// Take several positions and store the min and max of each in - /// turn - when all points have been added return the center/midpoint. + //! A utility to return the center of several points. + //! Take several positions and store the min and max of each in + //! turn - when all points have been added return the center/midpoint. class MidpointCalculator { public: - /// Default constructed with min and max initialized to opposites. + //! Default constructed with min and max initialized to opposites. MidpointCalculator() = default; - /// Call this for all positions you want to be considered. + //! Call this for all positions you want to be considered. void AddPosition(const AZ::Vector3& position) { m_minPosition = position.GetMin(m_minPosition); m_maxPosition = position.GetMax(m_maxPosition); } - /// Once all positions have been added, call this to return the midpoint. + //! Once all positions have been added, call this to return the midpoint. AZ::Vector3 CalculateMidpoint() const { return m_minPosition + (m_maxPosition - m_minPosition) * 0.5f; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp index 5603c1a0f7..fee0267766 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp @@ -1,29 +1,30 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "EditorTransformComponentSelection.h" -#include #include #include #include #include +#include #include #include #include #include -#include +#include #include #include +#include #include #include #include @@ -36,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -47,20 +47,40 @@ namespace AzToolsFramework AZ_CLASS_ALLOCATOR_IMPL(EditorTransformComponentSelection, AZ::SystemAllocator, 0) AZ_CVAR( - float, cl_viewportGizmoAxisLineWidth, 4.0f, nullptr, AZ::ConsoleFunctorFlags::Null, + float, + cl_viewportGizmoAxisLineWidth, + 4.0f, + nullptr, + AZ::ConsoleFunctorFlags::Null, "The width of the line for the viewport axis gizmo"); AZ_CVAR( - float, cl_viewportGizmoAxisLineLength, 0.7f, nullptr, AZ::ConsoleFunctorFlags::Null, + float, + cl_viewportGizmoAxisLineLength, + 0.7f, + nullptr, + AZ::ConsoleFunctorFlags::Null, "The length of the line for the viewport axis gizmo"); AZ_CVAR( - float, cl_viewportGizmoAxisLabelOffset, 1.15f, nullptr, AZ::ConsoleFunctorFlags::Null, + float, + cl_viewportGizmoAxisLabelOffset, + 1.15f, + nullptr, + AZ::ConsoleFunctorFlags::Null, "The offset of the label for the viewport axis gizmo"); AZ_CVAR( - float, cl_viewportGizmoAxisLabelSize, 1.0f, nullptr, AZ::ConsoleFunctorFlags::Null, + float, + cl_viewportGizmoAxisLabelSize, + 1.0f, + nullptr, + AZ::ConsoleFunctorFlags::Null, "The size of each label for the viewport axis gizmo"); AZ_CVAR( - AZ::Vector2, cl_viewportGizmoAxisScreenPosition, AZ::Vector2(0.045f, 0.9f), nullptr, - AZ::ConsoleFunctorFlags::Null, "The screen position of the gizmo in normalized (0-1) ndc space"); + AZ::Vector2, + cl_viewportGizmoAxisScreenPosition, + AZ::Vector2(0.045f, 0.9f), + nullptr, + AZ::ConsoleFunctorFlags::Null, + "The screen position of the gizmo in normalized (0-1) ndc space"); // strings related to new viewport interaction model (EditorTransformComponentSelection) static const char* const s_togglePivotTitleRightClick = "Toggle pivot"; @@ -125,7 +145,8 @@ namespace AzToolsFramework static const int s_defaultViewportId = 0; - static const float s_pivotSize = 0.075f; ///< The size of the pivot (box) to render when selected. + static const float s_pivotSize = 0.075f; // the size of the pivot (box) to render when selected + // data passed to manipulators when processing mouse interactions // m_entityIds should be sorted based on the entity hierarchy // (see SortEntitiesByLocationInHierarchy and BuildSortedEntityIdVectorFromEntityIdContainer) @@ -146,8 +167,7 @@ namespace AzToolsFramework bool OptionalFrame::HasTransformOverride() const { - return m_translationOverride.has_value() - || m_orientationOverride.has_value(); + return m_translationOverride.has_value() || m_orientationOverride.has_value(); } bool OptionalFrame::HasEntityOverride() const @@ -226,7 +246,7 @@ namespace AzToolsFramework return mouseInteraction.m_mouseInteraction.m_mouseButtons.Middle() && mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down && (mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Alt() || - mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl()); + mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl()); } static bool ManipulatorDitto(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) @@ -263,8 +283,7 @@ namespace AzToolsFramework } } - static EditorTransformComponentSelectionRequests::Pivot TogglePivotMode( - const EditorTransformComponentSelectionRequests::Pivot pivot) + static EditorTransformComponentSelectionRequests::Pivot TogglePivotMode(const EditorTransformComponentSelectionRequests::Pivot pivot) { switch (pivot) { @@ -282,8 +301,7 @@ namespace AzToolsFramework template static AZStd::vector EntityIdVectorFromContainer(const EntityIdContainer& entityIdContainer) { - static_assert(AZStd::is_same::value, - "Container type is not an EntityId"); + static_assert(AZStd::is_same::value, "Container type is not an EntityId"); AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); return AZStd::vector(entityIdContainer.begin(), entityIdContainer.end()); @@ -293,8 +311,7 @@ namespace AzToolsFramework template static AZStd::vector EntityIdVectorFromMap(const EntityIdMap& entityIdMap) { - static_assert(AZStd::is_same::value, - "Container key type is not an EntityId"); + static_assert(AZStd::is_same::value, "Container key type is not an EntityId"); AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -318,10 +335,15 @@ namespace AzToolsFramework template static void BoxSelectAddRemoveToEntitySelection( - const AZStd::optional& boxSelect, const AzFramework::ScreenPoint& screenPosition, const AZ::EntityId visibleEntityId, - const EntityIdContainer& incomingEntityIds, EntityIdContainer& outgoingEntityIds, + const AZStd::optional& boxSelect, + const AzFramework::ScreenPoint& screenPosition, + const AZ::EntityId visibleEntityId, + const EntityIdContainer& incomingEntityIds, + EntityIdContainer& outgoingEntityIds, EditorTransformComponentSelection& entityTransformComponentSelection, - EntitySelectFuncType selectFunc1, EntitySelectFuncType selectFunc2, Compare outgoingCheck) + EntitySelectFuncType selectFunc1, + EntitySelectFuncType selectFunc2, + Compare outgoingCheck) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -349,10 +371,14 @@ namespace AzToolsFramework template static void EntityBoxSelectUpdateGeneral( - const AZStd::optional& boxSelect, EditorTransformComponentSelection& editorTransformComponentSelection, - const EntityIdContainer& activeSelectedEntityIds, EntityIdContainer& selectedEntityIdsBeforeBoxSelect, - EntityIdContainer& potentialSelectedEntityIds, EntityIdContainer& potentialDeselectedEntityIds, - const EditorVisibleEntityDataCache& entityDataCache, const int viewportId, + const AZStd::optional& boxSelect, + EditorTransformComponentSelection& editorTransformComponentSelection, + const EntityIdContainer& activeSelectedEntityIds, + EntityIdContainer& selectedEntityIdsBeforeBoxSelect, + EntityIdContainer& potentialSelectedEntityIds, + EntityIdContainer& potentialDeselectedEntityIds, + const EditorVisibleEntityDataCache& entityDataCache, + const int viewportId, const ViewportInteraction::KeyboardModifiers currentKeyboardModifiers, const ViewportInteraction::KeyboardModifiers& previousKeyboardModifiers) { @@ -382,8 +408,7 @@ namespace AzToolsFramework for (size_t entityCacheIndex = 0; entityCacheIndex < entityDataCache.VisibleEntityDataCount(); ++entityCacheIndex) { - if ( entityDataCache.IsVisibleEntityLocked(entityCacheIndex) - || !entityDataCache.IsVisibleEntityVisible(entityCacheIndex)) + if (entityDataCache.IsVisibleEntityLocked(entityCacheIndex) || !entityDataCache.IsVisibleEntityVisible(entityCacheIndex)) { continue; } @@ -396,10 +421,8 @@ namespace AzToolsFramework if (currentKeyboardModifiers.Ctrl()) { BoxSelectAddRemoveToEntitySelection( - boxSelect, screenPosition, entityId, - selectedEntityIdsBeforeBoxSelect, potentialDeselectedEntityIds, - editorTransformComponentSelection, - &EditorTransformComponentSelection::RemoveEntityFromSelection, + boxSelect, screenPosition, entityId, selectedEntityIdsBeforeBoxSelect, potentialDeselectedEntityIds, + editorTransformComponentSelection, &EditorTransformComponentSelection::RemoveEntityFromSelection, &EditorTransformComponentSelection::AddEntityToSelection, [](const typename EntityIdContainer::const_iterator entityId, const EntityIdContainer& entityIds) { @@ -409,10 +432,8 @@ namespace AzToolsFramework else { BoxSelectAddRemoveToEntitySelection( - boxSelect, screenPosition, entityId, - activeSelectedEntityIds, potentialSelectedEntityIds, - editorTransformComponentSelection, - &EditorTransformComponentSelection::AddEntityToSelection, + boxSelect, screenPosition, entityId, activeSelectedEntityIds, potentialSelectedEntityIds, + editorTransformComponentSelection, &EditorTransformComponentSelection::AddEntityToSelection, &EditorTransformComponentSelection::RemoveEntityFromSelection, [](const typename EntityIdContainer::const_iterator entityId, const EntityIdContainer& entityIds) { @@ -429,62 +450,53 @@ namespace AzToolsFramework for (auto& entityIdLookup : entityIdManipulators.m_lookups) { - entityIdLookup.second.m_initial = - AZ::Transform::CreateTranslation(GetWorldTranslation(entityIdLookup.first)); + entityIdLookup.second.m_initial = AZ::Transform::CreateTranslation(GetWorldTranslation(entityIdLookup.first)); } } static void DestroyCluster(const ViewportUi::ClusterId clusterId) { ViewportUi::ViewportUiRequestBus::Event( - ViewportUi::DefaultViewportId, - &ViewportUi::ViewportUiRequestBus::Events::RemoveCluster, - clusterId); + ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::RemoveCluster, clusterId); } static void SetViewportUiClusterVisible(const ViewportUi::ClusterId clusterId, const bool visible) { ViewportUi::ViewportUiRequestBus::Event( - ViewportUi::DefaultViewportId, - &ViewportUi::ViewportUiRequestBus::Events::SetClusterVisible, - clusterId, visible); + ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::SetClusterVisible, clusterId, visible); } static void SetViewportUiClusterActiveButton(const ViewportUi::ClusterId clusterId, const ViewportUi::ButtonId buttonId) { ViewportUi::ViewportUiRequestBus::Event( - ViewportUi::DefaultViewportId, - &ViewportUi::ViewportUiRequestBus::Events::SetClusterActiveButton, - clusterId, buttonId); + ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::SetClusterActiveButton, clusterId, buttonId); } static ViewportUi::ButtonId RegisterClusterButton(const ViewportUi::ClusterId clusterId, const char* iconName) { ViewportUi::ButtonId buttonId; ViewportUi::ViewportUiRequestBus::EventResult( - buttonId, ViewportUi::DefaultViewportId, - &ViewportUi::ViewportUiRequestBus::Events::CreateClusterButton, - clusterId, AZStd::string::format(":/stylesheet/img/UI20/toolbar/%s.svg", iconName)); + buttonId, ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateClusterButton, clusterId, + AZStd::string::format(":/stylesheet/img/UI20/toolbar/%s.svg", iconName)); return buttonId; } // return either center or entity pivot - static AZ::Vector3 CalculatePivotTranslation( - const AZ::EntityId entityId, const EditorTransformComponentSelectionRequests::Pivot pivot) + static AZ::Vector3 CalculatePivotTranslation(const AZ::EntityId entityId, const EditorTransformComponentSelectionRequests::Pivot pivot) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity(); - AZ::TransformBus::EventResult( - worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM); + AZ::TransformBus::EventResult(worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM); return worldFromLocal.TransformPoint(CalculateCenterOffset(entityId, pivot)); } void EditorTransformComponentSelection::UpdateSpaceCluster(const ReferenceFrame referenceFrame) { - auto buttonIdFromFrameFn = [this](const ReferenceFrame referenceFrame) { + auto buttonIdFromFrameFn = [this](const ReferenceFrame referenceFrame) + { switch (referenceFrame) { case ReferenceFrame::Local: @@ -498,14 +510,13 @@ namespace AzToolsFramework }; ViewportUi::ViewportUiRequestBus::Event( - ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::SetClusterActiveButton, m_spaceCluster.m_spaceClusterId, - buttonIdFromFrameFn(referenceFrame)); + ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::SetClusterActiveButton, + m_spaceCluster.m_spaceClusterId, buttonIdFromFrameFn(referenceFrame)); } namespace ETCS { - PivotOrientationResult CalculatePivotOrientation( - const AZ::EntityId entityId, const ReferenceFrame referenceFrame) + PivotOrientationResult CalculatePivotOrientation(const AZ::EntityId entityId, const ReferenceFrame referenceFrame) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -515,21 +526,17 @@ namespace AzToolsFramework switch (referenceFrame) { case ReferenceFrame::Local: - AZ::TransformBus::EventResult( - result.m_worldOrientation, entityId, - &AZ::TransformBus::Events::GetWorldRotationQuaternion); + AZ::TransformBus::EventResult(result.m_worldOrientation, entityId, &AZ::TransformBus::Events::GetWorldRotationQuaternion); break; case ReferenceFrame::Parent: { AZ::EntityId parentId; - AZ::TransformBus::EventResult( - parentId, entityId, &AZ::TransformBus::Events::GetParentId); + AZ::TransformBus::EventResult(parentId, entityId, &AZ::TransformBus::Events::GetParentId); if (parentId.IsValid()) { AZ::TransformBus::EventResult( - result.m_worldOrientation, parentId, - &AZ::TransformBus::Events::GetWorldRotationQuaternion); + result.m_worldOrientation, parentId, &AZ::TransformBus::Events::GetWorldRotationQuaternion); result.m_parentId = parentId; } @@ -559,8 +566,7 @@ namespace AzToolsFramework { // check if this entity has a parent AZ::EntityId parentId; - AZ::TransformBus::EventResult( - parentId, entityIdLookupIt->first, &AZ::TransformBus::Events::GetParentId); + AZ::TransformBus::EventResult(parentId, entityIdLookupIt->first, &AZ::TransformBus::Events::GetParentId); // if no parent, space will be world, terminate if (!parentId.IsValid()) @@ -575,9 +581,7 @@ namespace AzToolsFramework if (!commonParentId.IsValid()) { commonParentId = parentId; - AZ::TransformBus::EventResult( - result.m_worldOrientation, parentId, - &AZ::TransformBus::Events::GetWorldRotationQuaternion); + AZ::TransformBus::EventResult(result.m_worldOrientation, parentId, &AZ::TransformBus::Events::GetWorldRotationQuaternion); } // if we know we still have a parent in common @@ -602,8 +606,7 @@ namespace AzToolsFramework static AZ::Vector3 CalculatePivotTranslationForEntityIds( const EntityIdMap& entityIdMap, const EditorTransformComponentSelectionRequests::Pivot pivot) { - static_assert(AZStd::is_same::value, - "Container key type is not an EntityId"); + static_assert(AZStd::is_same::value, "Container key type is not an EntityId"); AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -628,11 +631,9 @@ namespace AzToolsFramework namespace ETCS { template - PivotOrientationResult CalculatePivotOrientationForEntityIds( - const EntityIdMap& entityIdMap, const ReferenceFrame referenceFrame) + PivotOrientationResult CalculatePivotOrientationForEntityIds(const EntityIdMap& entityIdMap, const ReferenceFrame referenceFrame) { - static_assert(AZStd::is_same::value, - "Container key type is not an EntityId"); + static_assert(AZStd::is_same::value, "Container key type is not an EntityId"); AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -660,12 +661,11 @@ namespace AzToolsFramework { template PivotOrientationResult CalculateSelectionPivotOrientation( - const EntityIdMap& entityIdMap, const OptionalFrame& pivotOverrideFrame, - const ReferenceFrame referenceFrame) + const EntityIdMap& entityIdMap, const OptionalFrame& pivotOverrideFrame, const ReferenceFrame referenceFrame) { - static_assert(AZStd::is_same::value, - "Container key type is not an EntityId"); - static_assert(AZStd::is_same::value, + static_assert(AZStd::is_same::value, "Container key type is not an EntityId"); + static_assert( + AZStd::is_same::value, "Container value type is not an EntityIdManipulators::Lookup"); AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -728,20 +728,16 @@ namespace AzToolsFramework { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); - return pivotOverrideFrame.m_translationOverride.value_or( - CalculatePivotTranslationForEntityIds(entityIdMap, pivot)); + return pivotOverrideFrame.m_translationOverride.value_or(CalculatePivotTranslationForEntityIds(entityIdMap, pivot)); } template static AZ::Quaternion RecalculateAverageManipulatorOrientation( - const EntityIdMap& entityIdMap, - const OptionalFrame& pivotOverrideFrame, - const ReferenceFrame referenceFrame) + const EntityIdMap& entityIdMap, const OptionalFrame& pivotOverrideFrame, const ReferenceFrame referenceFrame) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); - return ETCS::CalculateSelectionPivotOrientation( - entityIdMap, pivotOverrideFrame, referenceFrame).m_worldOrientation; + return ETCS::CalculateSelectionPivotOrientation(entityIdMap, pivotOverrideFrame, referenceFrame).m_worldOrientation; } template @@ -756,15 +752,12 @@ namespace AzToolsFramework // return final transform, if we have an override for translation use that, otherwise // use centered translation of selection return AZ::Transform::CreateFromQuaternionAndTranslation( - RecalculateAverageManipulatorOrientation( - entityIdMap, pivotOverrideFrame, referenceFrame), - RecalculateAverageManipulatorTranslation( - entityIdMap, pivotOverrideFrame, pivot)); + RecalculateAverageManipulatorOrientation(entityIdMap, pivotOverrideFrame, referenceFrame), + RecalculateAverageManipulatorTranslation(entityIdMap, pivotOverrideFrame, pivot)); } template - static void BuildSortedEntityIdVectorFromEntityIdMap( - const EntityIdMap& entityIds, EntityIdList& sortedEntityIdsOut) + static void BuildSortedEntityIdVectorFromEntityIdMap(const EntityIdMap& entityIds, EntityIdList& sortedEntityIdsOut) { sortedEntityIdsOut = EntityIdVectorFromMap(entityIds); SortEntitiesByLocationInHierarchy(sortedEntityIdsOut); @@ -777,8 +770,7 @@ namespace AzToolsFramework for (auto& entityIdLookup : entityManipulators.m_lookups) { AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity(); - AZ::TransformBus::EventResult( - worldFromLocal, entityIdLookup.first, &AZ::TransformBus::Events::GetWorldTM); + AZ::TransformBus::EventResult(worldFromLocal, entityIdLookup.first, &AZ::TransformBus::Events::GetWorldTM); entityIdLookup.second.m_initial = worldFromLocal; } @@ -804,11 +796,13 @@ namespace AzToolsFramework template static void UpdateTranslationManipulator( - const Action& action, const EntityIdContainer& entityIdContainer, + const Action& action, + const EntityIdContainer& entityIdContainer, EntityIdManipulators& entityIdManipulators, OptionalFrame& pivotOverrideFrame, ViewportInteraction::KeyboardModifiers& prevModifiers, - bool& transformChangedInternally, const AZStd::optional spaceLock) + bool& transformChangedInternally, + const AZStd::optional spaceLock) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -817,8 +811,7 @@ namespace AzToolsFramework if (action.m_modifiers.Ctrl()) { // moving with ctrl - setting override - pivotOverrideFrame.m_translationOverride = - entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); + pivotOverrideFrame.m_translationOverride = entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); InitializeTranslationLookup(entityIdManipulators); } else @@ -827,8 +820,7 @@ namespace AzToolsFramework // note: used for parent and world depending on the current reference frame const auto pivotOrientation = - ETCS::CalculateSelectionPivotOrientation( - entityIdManipulators.m_lookups, pivotOverrideFrame, referenceFrame); + ETCS::CalculateSelectionPivotOrientation(entityIdManipulators.m_lookups, pivotOverrideFrame, referenceFrame); // note: must use sorted entityIds based on hierarchy order when updating transforms for (AZ::EntityId entityId : entityIdContainer) @@ -847,46 +839,37 @@ namespace AzToolsFramework { // move in each entities local space at once AZ::Quaternion worldOrientation = AZ::Quaternion::CreateIdentity(); - AZ::TransformBus::EventResult( - worldOrientation, entityId, &AZ::TransformBus::Events::GetWorldRotationQuaternion); + AZ::TransformBus::EventResult(worldOrientation, entityId, &AZ::TransformBus::Events::GetWorldRotationQuaternion); - const AZ::Transform space = - entityIdManipulators.m_manipulators->GetLocalTransform().GetInverse() * - AZ::Transform::CreateFromQuaternionAndTranslation( - worldOrientation, worldTranslation); + const AZ::Transform space = entityIdManipulators.m_manipulators->GetLocalTransform().GetInverse() * + AZ::Transform::CreateFromQuaternionAndTranslation(worldOrientation, worldTranslation); - const AZ::Vector3 localOffset = space.TransformVector(action.LocalPositionOffset()); + const AZ::Vector3 localOffset = space.TransformVector(action.LocalPositionOffset()); if (action.m_modifiers != prevModifiers) { - entityItLookupIt->second.m_initial = - AZ::Transform::CreateTranslation(worldTranslation - localOffset); + entityItLookupIt->second.m_initial = AZ::Transform::CreateTranslation(worldTranslation - localOffset); } ETCS::SetEntityWorldTranslation( - entityId, entityItLookupIt->second.m_initial.GetTranslation() + localOffset, - transformChangedInternally); + entityId, entityItLookupIt->second.m_initial.GetTranslation() + localOffset, transformChangedInternally); } break; case ReferenceFrame::Parent: case ReferenceFrame::World: { - AZ::Quaternion offsetRotation = - pivotOrientation.m_worldOrientation * - QuaternionFromTransformNoScaling( - entityIdManipulators.m_manipulators->GetLocalTransform().GetInverse()); + AZ::Quaternion offsetRotation = pivotOrientation.m_worldOrientation * + QuaternionFromTransformNoScaling(entityIdManipulators.m_manipulators->GetLocalTransform().GetInverse()); const AZ::Vector3 localOffset = offsetRotation.TransformVector(action.LocalPositionOffset()); if (action.m_modifiers != prevModifiers) { - entityItLookupIt->second.m_initial = - AZ::Transform::CreateTranslation(worldTranslation - localOffset); + entityItLookupIt->second.m_initial = AZ::Transform::CreateTranslation(worldTranslation - localOffset); } ETCS::SetEntityWorldTranslation( - entityId, entityItLookupIt->second.m_initial.GetTranslation() + localOffset, - transformChangedInternally); + entityId, entityItLookupIt->second.m_initial.GetTranslation() + localOffset, transformChangedInternally); } break; } @@ -895,8 +878,7 @@ namespace AzToolsFramework // if transform pivot override has been set, make sure to update it when we move it if (pivotOverrideFrame.m_translationOverride) { - pivotOverrideFrame.m_translationOverride = - entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); + pivotOverrideFrame.m_translationOverride = entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); } } @@ -904,8 +886,10 @@ namespace AzToolsFramework } static void HandleAccents( - const bool hasSelectedEntities, const AZ::EntityId entityIdUnderCursor, - const bool ctrlHeld, AZ::EntityId& hoveredEntityId, + const bool hasSelectedEntities, + const AZ::EntityId entityIdUnderCursor, + const bool ctrlHeld, + AZ::EntityId& hoveredEntityId, const ViewportInteraction::MouseButtons mouseButtons, const bool usingBoxSelect) { @@ -914,13 +898,11 @@ namespace AzToolsFramework const bool invalidMouseButtonHeld = mouseButtons.Middle() || mouseButtons.Right(); if ((hoveredEntityId.IsValid() && hoveredEntityId != entityIdUnderCursor) || - (hasSelectedEntities && !ctrlHeld && hoveredEntityId.IsValid()) || - invalidMouseButtonHeld) + (hasSelectedEntities && !ctrlHeld && hoveredEntityId.IsValid()) || invalidMouseButtonHeld) { if (hoveredEntityId.IsValid()) { - ToolsApplicationRequestBus::Broadcast( - &ToolsApplicationRequests::SetEntityHighlighted, hoveredEntityId, false); + ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetEntityHighlighted, hoveredEntityId, false); hoveredEntityId.SetInvalid(); } @@ -930,8 +912,7 @@ namespace AzToolsFramework { if (entityIdUnderCursor.IsValid()) { - ToolsApplicationRequestBus::Broadcast( - &ToolsApplicationRequests::SetEntityHighlighted, entityIdUnderCursor, true); + ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetEntityHighlighted, entityIdUnderCursor, true); hoveredEntityId = entityIdUnderCursor; } @@ -946,15 +927,13 @@ namespace AzToolsFramework // get unsnapped terrain position (world space) AZ::Vector3 worldSurfacePosition; ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult( - worldSurfacePosition, viewportId, - &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain, + worldSurfacePosition, viewportId, &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain, mouseInteraction.m_mousePick.m_screenCoordinates); // convert to local space - snap if enabled const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId); const AZ::Vector3 finalSurfacePosition = gridSnapParams.m_gridSnap - ? CalculateSnappedTerrainPosition( - worldSurfacePosition, AZ::Transform::CreateIdentity(), viewportId, gridSnapParams.m_gridSize) + ? CalculateSnappedTerrainPosition(worldSurfacePosition, AZ::Transform::CreateIdentity(), viewportId, gridSnapParams.m_gridSize) : worldSurfacePosition; return finalSurfacePosition; @@ -981,10 +960,9 @@ namespace AzToolsFramework for (AZ::EntityId entityId : entityIds) { AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity(); - AZ::TransformBus::EventResult( - worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM); + AZ::TransformBus::EventResult(worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM); - transformsBefore.insert({ entityId, worldFromLocal }); + transformsBefore.insert({ entityId, worldFromLocal }); } return transformsBefore; @@ -992,8 +970,7 @@ namespace AzToolsFramework // ask the visible entity data cache if the entity is selectable in the viewport // (useful in the context of drawing when we only care about entities we can see) - static bool SelectableInVisibleViewportCache( - const EditorVisibleEntityDataCache& entityDataCache, const AZ::EntityId entityId) + static bool SelectableInVisibleViewportCache(const EditorVisibleEntityDataCache& entityDataCache, const AZ::EntityId entityId) { if (auto entityIndex = entityDataCache.GetVisibleEntityIndexFromId(entityId)) { @@ -1021,15 +998,12 @@ namespace AzToolsFramework // is handled internally - this call is often required after an action/shortcut of some kind static void RefreshUiAfterChange(const EntityIdList& entitiyIds) { - EditorTransformChangeNotificationBus::Broadcast( - &EditorTransformChangeNotifications::OnEntityTransformChanged, entitiyIds); + EditorTransformChangeNotificationBus::Broadcast(&EditorTransformChangeNotifications::OnEntityTransformChanged, entitiyIds); - ToolsApplicationNotificationBus::Broadcast( - &ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values); + ToolsApplicationNotificationBus::Broadcast(&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values); } - EditorTransformComponentSelection::EditorTransformComponentSelection( - const EditorVisibleEntityDataCache* entityDataCache) + EditorTransformComponentSelection::EditorTransformComponentSelection(const EditorVisibleEntityDataCache* entityDataCache) : m_entityDataCache(entityDataCache) { const AzFramework::EntityContextId entityContextId = GetEntityContextId(); @@ -1090,101 +1064,96 @@ namespace AzToolsFramework m_boxSelect.InstallLeftMouseDown( [this, entityBoxSelectData](const ViewportInteraction::MouseInteractionEvent& /*mouseInteraction*/) - { - // begin selection undo/redo command - entityBoxSelectData->m_boxSelectSelectionCommand = - AZStd::make_unique(EntityIdList(), s_entityBoxSelectUndoRedoDesc); - // grab currently selected entities - entityBoxSelectData->m_selectedEntityIdsBeforeBoxSelect = m_selectedEntityIds; - }); + { + // begin selection undo/redo command + entityBoxSelectData->m_boxSelectSelectionCommand = + AZStd::make_unique(EntityIdList(), s_entityBoxSelectUndoRedoDesc); + // grab currently selected entities + entityBoxSelectData->m_selectedEntityIdsBeforeBoxSelect = m_selectedEntityIds; + }); m_boxSelect.InstallMouseMove( [this, entityBoxSelectData](const ViewportInteraction::MouseInteractionEvent& mouseInteraction) - { - EntityBoxSelectUpdateGeneral( - m_boxSelect.BoxRegion(), *this, m_selectedEntityIds, entityBoxSelectData->m_selectedEntityIdsBeforeBoxSelect, - entityBoxSelectData->m_potentialSelectedEntityIds, entityBoxSelectData->m_potentialDeselectedEntityIds, - *m_entityDataCache, mouseInteraction.m_mouseInteraction.m_interactionId.m_viewportId, - mouseInteraction.m_mouseInteraction.m_keyboardModifiers, - m_boxSelect.PreviousModifiers()); - }); + { + EntityBoxSelectUpdateGeneral( + m_boxSelect.BoxRegion(), *this, m_selectedEntityIds, entityBoxSelectData->m_selectedEntityIdsBeforeBoxSelect, + entityBoxSelectData->m_potentialSelectedEntityIds, entityBoxSelectData->m_potentialDeselectedEntityIds, + *m_entityDataCache, mouseInteraction.m_mouseInteraction.m_interactionId.m_viewportId, + mouseInteraction.m_mouseInteraction.m_keyboardModifiers, m_boxSelect.PreviousModifiers()); + }); m_boxSelect.InstallLeftMouseUp( [this, entityBoxSelectData]() - { - entityBoxSelectData->m_boxSelectSelectionCommand->UpdateSelection(EntityIdVectorFromContainer(m_selectedEntityIds)); - - // if we know a change in selection has occurred, record the undo step - if ( !entityBoxSelectData->m_potentialDeselectedEntityIds.empty() - || !entityBoxSelectData->m_potentialSelectedEntityIds.empty()) { - ScopedUndoBatch undoBatch(s_entityBoxSelectUndoRedoDesc); + entityBoxSelectData->m_boxSelectSelectionCommand->UpdateSelection(EntityIdVectorFromContainer(m_selectedEntityIds)); - // restore manipulator overrides when undoing - if (m_entityIdManipulators.m_manipulators && m_selectedEntityIds.empty()) + // if we know a change in selection has occurred, record the undo step + if (!entityBoxSelectData->m_potentialDeselectedEntityIds.empty() || + !entityBoxSelectData->m_potentialSelectedEntityIds.empty()) { - CreateEntityManipulatorDeselectCommand(undoBatch); - } + ScopedUndoBatch undoBatch(s_entityBoxSelectUndoRedoDesc); - entityBoxSelectData->m_boxSelectSelectionCommand->SetParent(undoBatch.GetUndoBatch()); - entityBoxSelectData->m_boxSelectSelectionCommand.release(); + // restore manipulator overrides when undoing + if (m_entityIdManipulators.m_manipulators && m_selectedEntityIds.empty()) + { + CreateEntityManipulatorDeselectCommand(undoBatch); + } - SetSelectedEntities(EntityIdVectorFromContainer(m_selectedEntityIds)); - // note: manipulators will be updated in AfterEntitySelectionChanged + entityBoxSelectData->m_boxSelectSelectionCommand->SetParent(undoBatch.GetUndoBatch()); + entityBoxSelectData->m_boxSelectSelectionCommand.release(); - // clear pivot override when selection is empty - if (m_selectedEntityIds.empty()) + SetSelectedEntities(EntityIdVectorFromContainer(m_selectedEntityIds)); + // note: manipulators will be updated in AfterEntitySelectionChanged + + // clear pivot override when selection is empty + if (m_selectedEntityIds.empty()) + { + m_pivotOverrideFrame.Reset(); + } + } + else { - m_pivotOverrideFrame.Reset(); + entityBoxSelectData->m_boxSelectSelectionCommand.reset(); } - } - else - { - entityBoxSelectData->m_boxSelectSelectionCommand.reset(); - } - entityBoxSelectData->m_potentialSelectedEntityIds.clear(); - entityBoxSelectData->m_potentialDeselectedEntityIds.clear(); - entityBoxSelectData->m_selectedEntityIdsBeforeBoxSelect.clear(); - }); + entityBoxSelectData->m_potentialSelectedEntityIds.clear(); + entityBoxSelectData->m_potentialDeselectedEntityIds.clear(); + entityBoxSelectData->m_selectedEntityIdsBeforeBoxSelect.clear(); + }); m_boxSelect.InstallDisplayScene( - [this, entityBoxSelectData] - (const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) - { - const auto modifiers = ViewportInteraction::KeyboardModifiers( - ViewportInteraction::TranslateKeyboardModifiers(QApplication::queryKeyboardModifiers())); - - if (m_boxSelect.PreviousModifiers() != modifiers) + [this, entityBoxSelectData](const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) { - EntityBoxSelectUpdateGeneral( - m_boxSelect.BoxRegion(), *this, m_selectedEntityIds, - entityBoxSelectData->m_selectedEntityIdsBeforeBoxSelect, - entityBoxSelectData->m_potentialSelectedEntityIds, - entityBoxSelectData->m_potentialDeselectedEntityIds, - *m_entityDataCache, viewportInfo.m_viewportId, modifiers, - m_boxSelect.PreviousModifiers()); - } + const auto modifiers = ViewportInteraction::KeyboardModifiers( + ViewportInteraction::TranslateKeyboardModifiers(QApplication::queryKeyboardModifiers())); - debugDisplay.DepthTestOff(); - debugDisplay.SetColor(s_selectedEntityAabbColor); + if (m_boxSelect.PreviousModifiers() != modifiers) + { + EntityBoxSelectUpdateGeneral( + m_boxSelect.BoxRegion(), *this, m_selectedEntityIds, entityBoxSelectData->m_selectedEntityIdsBeforeBoxSelect, + entityBoxSelectData->m_potentialSelectedEntityIds, entityBoxSelectData->m_potentialDeselectedEntityIds, + *m_entityDataCache, viewportInfo.m_viewportId, modifiers, m_boxSelect.PreviousModifiers()); + } - for (AZ::EntityId entityId : entityBoxSelectData->m_potentialSelectedEntityIds) - { - const auto entityIdIt = entityBoxSelectData->m_selectedEntityIdsBeforeBoxSelect.find(entityId); + debugDisplay.DepthTestOff(); + debugDisplay.SetColor(s_selectedEntityAabbColor); - // don't show box when re-adding from previous selection - if (entityIdIt != entityBoxSelectData->m_selectedEntityIdsBeforeBoxSelect.end()) + for (AZ::EntityId entityId : entityBoxSelectData->m_potentialSelectedEntityIds) { - continue; - } + const auto entityIdIt = entityBoxSelectData->m_selectedEntityIdsBeforeBoxSelect.find(entityId); - const AZ::Aabb bound = CalculateEditorEntitySelectionBounds(entityId, viewportInfo); - debugDisplay.DrawSolidBox(bound.GetMin(), bound.GetMax()); - } + // don't show box when re-adding from previous selection + if (entityIdIt != entityBoxSelectData->m_selectedEntityIdsBeforeBoxSelect.end()) + { + continue; + } - debugDisplay.DepthTestOn(); - }); + const AZ::Aabb bound = CalculateEditorEntitySelectionBounds(entityId, viewportInfo); + debugDisplay.DrawSolidBox(bound.GetMin(), bound.GetMax()); + } + + debugDisplay.DepthTestOn(); + }); } EntityManipulatorCommand::State EditorTransformComponentSelection::CreateManipulatorCommandStateFromSelf() const @@ -1197,14 +1166,9 @@ namespace AzToolsFramework return {}; } - return { - BuildPivotOverride( - m_pivotOverrideFrame.HasTranslationOverride(), - m_pivotOverrideFrame.HasOrientationOverride()), - TransformNormalizedScale( - m_entityIdManipulators.m_manipulators->GetLocalTransform()), - m_pivotOverrideFrame.m_pickedEntityIdOverride - }; + return { BuildPivotOverride(m_pivotOverrideFrame.HasTranslationOverride(), m_pivotOverrideFrame.HasOrientationOverride()), + TransformNormalizedScale(m_entityIdManipulators.m_manipulators->GetLocalTransform()), + m_pivotOverrideFrame.m_pickedEntityIdOverride }; } void EditorTransformComponentSelection::BeginRecordManipulatorCommand() @@ -1214,14 +1178,13 @@ namespace AzToolsFramework // we must have an existing parent undo batch active when beginning to record // a manipulator command UndoSystem::URSequencePoint* currentUndoOperation = nullptr; - ToolsApplicationRequests::Bus::BroadcastResult( - currentUndoOperation, &ToolsApplicationRequests::GetCurrentUndoBatch); + ToolsApplicationRequests::Bus::BroadcastResult(currentUndoOperation, &ToolsApplicationRequests::GetCurrentUndoBatch); if (currentUndoOperation) { // check here if translation or orientation override are set - m_manipulatorMoveCommand = AZStd::make_unique( - CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); + m_manipulatorMoveCommand = + AZStd::make_unique(CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); } } @@ -1234,10 +1197,11 @@ namespace AzToolsFramework m_manipulatorMoveCommand->SetManipulatorAfter(CreateManipulatorCommandStateFromSelf()); UndoSystem::URSequencePoint* currentUndoOperation = nullptr; - ToolsApplicationRequests::Bus::BroadcastResult( - currentUndoOperation, &ToolsApplicationRequests::GetCurrentUndoBatch); + ToolsApplicationRequests::Bus::BroadcastResult(currentUndoOperation, &ToolsApplicationRequests::GetCurrentUndoBatch); - AZ_Assert(currentUndoOperation, "The only way we should have reached this block is if " + AZ_Assert( + currentUndoOperation, + "The only way we should have reached this block is if " "m_manipulatorMoveCommand was created by calling BeginRecordManipulatorMouseMoveCommand. " "If we've reached this point and currentUndoOperation is null, something bad has happened " "in the undo system"); @@ -1254,18 +1218,15 @@ namespace AzToolsFramework { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); - AZStd::unique_ptr translationManipulators = - AZStd::make_unique( - TranslationManipulators::Dimensions::Three, - AZ::Transform::CreateIdentity(), AZ::Vector3::CreateOne()); + AZStd::unique_ptr translationManipulators = AZStd::make_unique( + TranslationManipulators::Dimensions::Three, AZ::Transform::CreateIdentity(), AZ::Vector3::CreateOne()); InitializeManipulators(*translationManipulators); ConfigureTranslationManipulatorAppearance3d(&*translationManipulators); translationManipulators->SetLocalTransform( - RecalculateAverageManipulatorTransform( - m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode, m_referenceFrame)); + RecalculateAverageManipulatorTransform(m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode, m_referenceFrame)); // lambdas capture shared_ptr by value to increment ref count auto manipulatorEntityIds = AZStd::make_shared(); @@ -1277,95 +1238,92 @@ namespace AzToolsFramework // linear translationManipulators->InstallLinearManipulatorMouseDownCallback( [this, manipulatorEntityIds]([[maybe_unused]] const LinearManipulator::Action& action) mutable - { - // important to sort entityIds based on hierarchy order when updating transforms - BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds->m_entityIds); + { + // important to sort entityIds based on hierarchy order when updating transforms + BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds->m_entityIds); - InitializeTranslationLookup(m_entityIdManipulators); + InitializeTranslationLookup(m_entityIdManipulators); - m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); - m_axisPreview.m_orientation = QuaternionFromTransformNoScaling( - m_entityIdManipulators.m_manipulators->GetLocalTransform()); + m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); + m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()); - // [ref 1.] - BeginRecordManipulatorCommand(); - }); + // [ref 1.] + BeginRecordManipulatorCommand(); + }); ViewportInteraction::KeyboardModifiers prevModifiers{}; translationManipulators->InstallLinearManipulatorMouseMoveCallback( [this, prevModifiers, manipulatorEntityIds](const LinearManipulator::Action& action) mutable -> void - { - UpdateTranslationManipulator( - action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers, + { + UpdateTranslationManipulator( + action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers, m_transformChangedInternally, m_spaceCluster.m_spaceLock); - }); + }); translationManipulators->InstallLinearManipulatorMouseUpCallback( [this]([[maybe_unused]] const LinearManipulator::Action& action) mutable - { - EndRecordManipulatorCommand(); - }); + { + EndRecordManipulatorCommand(); + }); // planar translationManipulators->InstallPlanarManipulatorMouseDownCallback( [this, manipulatorEntityIds]([[maybe_unused]] const PlanarManipulator::Action& action) - { - // important to sort entityIds based on hierarchy order when updating transforms - BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds->m_entityIds); + { + // important to sort entityIds based on hierarchy order when updating transforms + BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds->m_entityIds); - InitializeTranslationLookup(m_entityIdManipulators); + InitializeTranslationLookup(m_entityIdManipulators); - m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); - m_axisPreview.m_orientation = QuaternionFromTransformNoScaling( - m_entityIdManipulators.m_manipulators->GetLocalTransform()); + m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); + m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()); - // [ref 1.] - BeginRecordManipulatorCommand(); - }); + // [ref 1.] + BeginRecordManipulatorCommand(); + }); translationManipulators->InstallPlanarManipulatorMouseMoveCallback( [this, prevModifiers, manipulatorEntityIds](const PlanarManipulator::Action& action) mutable -> void - { - UpdateTranslationManipulator( - action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers, + { + UpdateTranslationManipulator( + action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers, m_transformChangedInternally, m_spaceCluster.m_spaceLock); - }); + }); translationManipulators->InstallPlanarManipulatorMouseUpCallback( [this, manipulatorEntityIds](const PlanarManipulator::Action& /*action*/) - { - EndRecordManipulatorCommand(); - }); + { + EndRecordManipulatorCommand(); + }); // surface translationManipulators->InstallSurfaceManipulatorMouseDownCallback( [this, manipulatorEntityIds]([[maybe_unused]] const SurfaceManipulator::Action& action) - { - BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds->m_entityIds); + { + BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds->m_entityIds); - InitializeTranslationLookup(m_entityIdManipulators); + InitializeTranslationLookup(m_entityIdManipulators); - m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); - m_axisPreview.m_orientation = QuaternionFromTransformNoScaling( - m_entityIdManipulators.m_manipulators->GetLocalTransform()); + m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); + m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()); - // [ref 1.] - BeginRecordManipulatorCommand(); - }); + // [ref 1.] + BeginRecordManipulatorCommand(); + }); translationManipulators->InstallSurfaceManipulatorMouseMoveCallback( [this, prevModifiers, manipulatorEntityIds](const SurfaceManipulator::Action& action) mutable -> void - { - UpdateTranslationManipulator( - action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers, + { + UpdateTranslationManipulator( + action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers, m_transformChangedInternally, m_spaceCluster.m_spaceLock); - }); + }); translationManipulators->InstallSurfaceManipulatorMouseUpCallback( [this, manipulatorEntityIds](const SurfaceManipulator::Action& /*action*/) - { - EndRecordManipulatorCommand(); - }); + { + EndRecordManipulatorCommand(); + }); // transfer ownership m_entityIdManipulators.m_manipulators = AZStd::move(translationManipulators); @@ -1381,18 +1339,12 @@ namespace AzToolsFramework InitializeManipulators(*rotationManipulators); rotationManipulators->SetLocalTransform( - RecalculateAverageManipulatorTransform( - m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode, m_referenceFrame)); + RecalculateAverageManipulatorTransform(m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode, m_referenceFrame)); // view - rotationManipulators->SetLocalAxes( - AZ::Vector3::CreateAxisX(), - AZ::Vector3::CreateAxisY(), - AZ::Vector3::CreateAxisZ()); + rotationManipulators->SetLocalAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ()); rotationManipulators->ConfigureView( - 2.0f, - AzFramework::ViewportColors::XAxisColor, - AzFramework::ViewportColors::YAxisColor, + 2.0f, AzFramework::ViewportColors::XAxisColor, AzFramework::ViewportColors::YAxisColor, AzFramework::ViewportColors::ZAxisColor); struct SharedRotationState @@ -1403,149 +1355,139 @@ namespace AzToolsFramework }; // lambdas capture shared_ptr by value to increment ref count - AZStd::shared_ptr sharedRotationState = - AZStd::make_shared(); + AZStd::shared_ptr sharedRotationState = AZStd::make_shared(); rotationManipulators->InstallLeftMouseDownCallback( [this, sharedRotationState](const AngularManipulator::Action& /*action*/) mutable -> void - { - sharedRotationState->m_savedOrientation = AZ::Quaternion::CreateIdentity(); - sharedRotationState->m_referenceFrameAtMouseDown = m_referenceFrame; - // important to sort entityIds based on hierarchy order when updating transforms - BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, sharedRotationState->m_entityIds); - - for (auto& entityIdLookup : m_entityIdManipulators.m_lookups) { - AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity(); - AZ::TransformBus::EventResult( - worldFromLocal, entityIdLookup.first, &AZ::TransformBus::Events::GetWorldTM); + sharedRotationState->m_savedOrientation = AZ::Quaternion::CreateIdentity(); + sharedRotationState->m_referenceFrameAtMouseDown = m_referenceFrame; + // important to sort entityIds based on hierarchy order when updating transforms + BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, sharedRotationState->m_entityIds); - entityIdLookup.second.m_initial = worldFromLocal; - } + for (auto& entityIdLookup : m_entityIdManipulators.m_lookups) + { + AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity(); + AZ::TransformBus::EventResult(worldFromLocal, entityIdLookup.first, &AZ::TransformBus::Events::GetWorldTM); - m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); - m_axisPreview.m_orientation = QuaternionFromTransformNoScaling( - m_entityIdManipulators.m_manipulators->GetLocalTransform()); + entityIdLookup.second.m_initial = worldFromLocal; + } - // [ref 1.] - BeginRecordManipulatorCommand(); - }); + m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); + m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()); + + // [ref 1.] + BeginRecordManipulatorCommand(); + }); ViewportInteraction::KeyboardModifiers prevModifiers{}; rotationManipulators->InstallMouseMoveCallback( - [this, prevModifiers, sharedRotationState] - (const AngularManipulator::Action& action) mutable -> void - { - const ReferenceFrame referenceFrame = m_spaceCluster.m_spaceLock.value_or(ReferenceFrameFromModifiers(action.m_modifiers)); - const AZ::Quaternion manipulatorOrientation = action.m_start.m_rotation * action.m_current.m_delta; - // store the pivot override frame when positioning the manipulator manually (ctrl) - // so we don't lose the orientation when adding/removing entities from the selection - if (action.m_modifiers.Ctrl()) - { - m_pivotOverrideFrame.m_orientationOverride = manipulatorOrientation; - } - - // only update the manipulator orientation if we're rotating in a local reference frame or we're - // manually modifying the manipulator orientation independent of the entity by holding ctrl - if ((sharedRotationState->m_referenceFrameAtMouseDown == ReferenceFrame::Local - && m_entityIdManipulators.m_lookups.size() == 1) || action.m_modifiers.Ctrl()) - { - m_entityIdManipulators.m_manipulators->SetLocalTransform( - AZ::Transform::CreateFromQuaternionAndTranslation( - manipulatorOrientation, - m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation())); - } - - // save state if we change the type of rotation we're doing to to prevent snapping - if (prevModifiers != action.m_modifiers) + [this, prevModifiers, sharedRotationState](const AngularManipulator::Action& action) mutable -> void { - UpdateInitialRotation(m_entityIdManipulators); - sharedRotationState->m_savedOrientation = action.m_current.m_delta.GetInverseFull(); - } + const ReferenceFrame referenceFrame = m_spaceCluster.m_spaceLock.value_or(ReferenceFrameFromModifiers(action.m_modifiers)); + const AZ::Quaternion manipulatorOrientation = action.m_start.m_rotation * action.m_current.m_delta; + // store the pivot override frame when positioning the manipulator manually (ctrl) + // so we don't lose the orientation when adding/removing entities from the selection + if (action.m_modifiers.Ctrl()) + { + m_pivotOverrideFrame.m_orientationOverride = manipulatorOrientation; + } - // allow the user to modify the orientation without moving the object if ctrl is held - if (action.m_modifiers.Ctrl()) - { - UpdateInitialRotation(m_entityIdManipulators); - sharedRotationState->m_savedOrientation = action.m_current.m_delta.GetInverseFull(); - } - else - { - const auto pivotOrientation = - ETCS::CalculateSelectionPivotOrientation( - m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, ReferenceFrame::Parent); + // only update the manipulator orientation if we're rotating in a local reference frame or we're + // manually modifying the manipulator orientation independent of the entity by holding ctrl + if ((sharedRotationState->m_referenceFrameAtMouseDown == ReferenceFrame::Local && + m_entityIdManipulators.m_lookups.size() == 1) || + action.m_modifiers.Ctrl()) + { + m_entityIdManipulators.m_manipulators->SetLocalTransform(AZ::Transform::CreateFromQuaternionAndTranslation( + manipulatorOrientation, m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation())); + } - // note: must use sorted entityIds based on hierarchy order when updating transforms - for (AZ::EntityId entityId : sharedRotationState->m_entityIds) + // save state if we change the type of rotation we're doing to to prevent snapping + if (prevModifiers != action.m_modifiers) { - auto entityIdLookupIt = m_entityIdManipulators.m_lookups.find(entityId); - if (entityIdLookupIt == m_entityIdManipulators.m_lookups.end()) - { - continue; - } + UpdateInitialRotation(m_entityIdManipulators); + sharedRotationState->m_savedOrientation = action.m_current.m_delta.GetInverseFull(); + } - // make sure we take into account how we move the axis independent of object - // if Ctrl was held to adjust the orientation of the axes separately - const AZ::Transform offsetRotation = AZ::Transform::CreateFromQuaternion( - sharedRotationState->m_savedOrientation * action.m_current.m_delta); + // allow the user to modify the orientation without moving the object if ctrl is held + if (action.m_modifiers.Ctrl()) + { + UpdateInitialRotation(m_entityIdManipulators); + sharedRotationState->m_savedOrientation = action.m_current.m_delta.GetInverseFull(); + } + else + { + const auto pivotOrientation = ETCS::CalculateSelectionPivotOrientation( + m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, ReferenceFrame::Parent); - switch (referenceFrame) + // note: must use sorted entityIds based on hierarchy order when updating transforms + for (AZ::EntityId entityId : sharedRotationState->m_entityIds) { - case ReferenceFrame::Local: + auto entityIdLookupIt = m_entityIdManipulators.m_lookups.find(entityId); + if (entityIdLookupIt == m_entityIdManipulators.m_lookups.end()) { - const AZ::Quaternion rotation = entityIdLookupIt->second.m_initial.GetRotation().GetNormalized(); - const AZ::Vector3 position = entityIdLookupIt->second.m_initial.GetTranslation(); - const float scale = entityIdLookupIt->second.m_initial.GetUniformScale(); - - const AZ::Vector3 centerOffset = CalculateCenterOffset(entityId, m_pivotMode); - - // scale -> rotate -> translate - SetEntityWorldTransform( - entityId, - AZ::Transform::CreateTranslation(position) * - AZ::Transform::CreateFromQuaternion(rotation) * - AZ::Transform::CreateTranslation(centerOffset) * offsetRotation * - AZ::Transform::CreateTranslation(-centerOffset) * - AZ::Transform::CreateUniformScale(scale)); + continue; } - break; - case ReferenceFrame::Parent: + + // make sure we take into account how we move the axis independent of object + // if Ctrl was held to adjust the orientation of the axes separately + const AZ::Transform offsetRotation = + AZ::Transform::CreateFromQuaternion(sharedRotationState->m_savedOrientation * action.m_current.m_delta); + + switch (referenceFrame) { - const AZ::Transform pivotTransform = - AZ::Transform::CreateFromQuaternionAndTranslation( + case ReferenceFrame::Local: + { + const AZ::Quaternion rotation = entityIdLookupIt->second.m_initial.GetRotation().GetNormalized(); + const AZ::Vector3 position = entityIdLookupIt->second.m_initial.GetTranslation(); + const float scale = entityIdLookupIt->second.m_initial.GetUniformScale(); + + const AZ::Vector3 centerOffset = CalculateCenterOffset(entityId, m_pivotMode); + + // scale -> rotate -> translate + SetEntityWorldTransform( + entityId, + AZ::Transform::CreateTranslation(position) * AZ::Transform::CreateFromQuaternion(rotation) * + AZ::Transform::CreateTranslation(centerOffset) * offsetRotation * + AZ::Transform::CreateTranslation(-centerOffset) * AZ::Transform::CreateUniformScale(scale)); + } + break; + case ReferenceFrame::Parent: + { + const AZ::Transform pivotTransform = AZ::Transform::CreateFromQuaternionAndTranslation( pivotOrientation.m_worldOrientation, m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation()); - const AZ::Transform transformInPivotSpace = - pivotTransform.GetInverse() * entityIdLookupIt->second.m_initial; + const AZ::Transform transformInPivotSpace = + pivotTransform.GetInverse() * entityIdLookupIt->second.m_initial; - SetEntityWorldTransform(entityId, pivotTransform * offsetRotation * transformInPivotSpace); - } - break; - case ReferenceFrame::World: - { - const AZ::Transform pivotTransform = - AZ::Transform::CreateFromQuaternionAndTranslation( + SetEntityWorldTransform(entityId, pivotTransform * offsetRotation * transformInPivotSpace); + } + break; + case ReferenceFrame::World: + { + const AZ::Transform pivotTransform = AZ::Transform::CreateFromQuaternionAndTranslation( AZ::Quaternion::CreateIdentity(), m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation()); - const AZ::Transform transformInPivotSpace = - pivotTransform.GetInverse() * entityIdLookupIt->second.m_initial; + const AZ::Transform transformInPivotSpace = + pivotTransform.GetInverse() * entityIdLookupIt->second.m_initial; - SetEntityWorldTransform(entityId, pivotTransform * offsetRotation * transformInPivotSpace); + SetEntityWorldTransform(entityId, pivotTransform * offsetRotation * transformInPivotSpace); + } + break; } - break; } } - } - prevModifiers = action.m_modifiers; - }); + prevModifiers = action.m_modifiers; + }); rotationManipulators->InstallLeftMouseUpCallback( [this](const AngularManipulator::Action& /*action*/) - { - EndRecordManipulatorCommand(); - }); + { + EndRecordManipulatorCommand(); + }); rotationManipulators->Register(g_mainManipulatorManagerId); @@ -1557,30 +1499,20 @@ namespace AzToolsFramework { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); - AZStd::unique_ptr scaleManipulators = - AZStd::make_unique(AZ::Transform::CreateIdentity()); + AZStd::unique_ptr scaleManipulators = AZStd::make_unique(AZ::Transform::CreateIdentity()); InitializeManipulators(*scaleManipulators); scaleManipulators->SetLocalTransform( - RecalculateAverageManipulatorTransform( - m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode, m_referenceFrame)); + RecalculateAverageManipulatorTransform(m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode, m_referenceFrame)); - scaleManipulators->SetAxes( - AZ::Vector3::CreateAxisX(), - AZ::Vector3::CreateAxisY(), - AZ::Vector3::CreateAxisZ()); - scaleManipulators->ConfigureView( - 2.0f, - AZ::Color::CreateOne(), - AZ::Color::CreateOne(), - AZ::Color::CreateOne()); + scaleManipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ()); + scaleManipulators->ConfigureView(2.0f, AZ::Color::CreateOne(), AZ::Color::CreateOne(), AZ::Color::CreateOne()); // lambdas capture shared_ptr by value to increment ref count auto manipulatorEntityIds = AZStd::make_shared(); - auto uniformLeftMouseDownCallback = - [this, manipulatorEntityIds]([[maybe_unused]] const LinearManipulator::Action& action) + auto uniformLeftMouseDownCallback = [this, manipulatorEntityIds]([[maybe_unused]] const LinearManipulator::Action& action) { // important to sort entityIds based on hierarchy order when updating transforms BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds->m_entityIds); @@ -1588,22 +1520,19 @@ namespace AzToolsFramework for (auto& entityIdLookup : m_entityIdManipulators.m_lookups) { AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity(); - AZ::TransformBus::EventResult( - worldFromLocal, entityIdLookup.first, &AZ::TransformBus::Events::GetWorldTM); + AZ::TransformBus::EventResult(worldFromLocal, entityIdLookup.first, &AZ::TransformBus::Events::GetWorldTM); entityIdLookup.second.m_initial = worldFromLocal; } m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); - m_axisPreview.m_orientation = QuaternionFromTransformNoScaling( - m_entityIdManipulators.m_manipulators->GetLocalTransform()); + m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()); }; auto uniformLeftMouseUpCallback = [this, manipulatorEntityIds]([[maybe_unused]] const LinearManipulator::Action& action) { - m_entityIdManipulators.m_manipulators->SetLocalTransform( - RecalculateAverageManipulatorTransform( - m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode, m_referenceFrame)); + m_entityIdManipulators.m_manipulators->SetLocalTransform(RecalculateAverageManipulatorTransform( + m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode, m_referenceFrame)); }; auto uniformLeftMouseMoveCallback = [this, manipulatorEntityIds](const LinearManipulator::Action& action) @@ -1620,7 +1549,8 @@ namespace AzToolsFramework const AZ::Transform initial = entityIdLookupIt->second.m_initial; const float initialScale = initial.GetUniformScale(); - const auto sumVectorElements = [](const AZ::Vector3& vec) { + const auto sumVectorElements = [](const AZ::Vector3& vec) + { return vec.GetX() + vec.GetY() + vec.GetZ(); }; @@ -1630,19 +1560,16 @@ namespace AzToolsFramework if (action.m_modifiers.Alt()) { - const AZ::Transform pivotTransform = TransformNormalizedScale( - entityIdLookupIt->second.m_initial); - const AZ::Transform transformInPivotSpace = - pivotTransform.GetInverse() * initial; + const AZ::Transform pivotTransform = TransformNormalizedScale(entityIdLookupIt->second.m_initial); + const AZ::Transform transformInPivotSpace = pivotTransform.GetInverse() * initial; SetEntityWorldTransform(entityId, pivotTransform * scaleTransform * transformInPivotSpace); } else { - const AZ::Transform pivotTransform = TransformNormalizedScale( - m_entityIdManipulators.m_manipulators->GetLocalTransform()); - const AZ::Transform transformInPivotSpace = - pivotTransform.GetInverse() * initial; + const AZ::Transform pivotTransform = + TransformNormalizedScale(m_entityIdManipulators.m_manipulators->GetLocalTransform()); + const AZ::Transform transformInPivotSpace = pivotTransform.GetInverse() * initial; SetEntityWorldTransform(entityId, pivotTransform * scaleTransform * transformInPivotSpace); } @@ -1674,11 +1601,10 @@ namespace AzToolsFramework { if (IsSelectableInViewport(entityId)) { - const AZ::ComponentId transformComponentId = GetTransformComponentId(entityId); + const AZ::ComponentId transformComponentId = GetTransformComponentId(entityId); if (transformComponentId != AZ::InvalidComponentId) { - manipulators.AddEntityComponentIdPair( - AZ::EntityComponentIdPair(entityId, transformComponentId)); + manipulators.AddEntityComponentIdPair(AZ::EntityComponentIdPair(entityId, transformComponentId)); m_entityIdManipulators.m_lookups.insert_key(entityId); } } @@ -1692,11 +1618,10 @@ namespace AzToolsFramework { if (IsSelectableInViewport(entityId)) { - const AZ::ComponentId transformComponentId = GetTransformComponentId(entityId); + const AZ::ComponentId transformComponentId = GetTransformComponentId(entityId); if (transformComponentId != AZ::InvalidComponentId) { - manipulators.AddEntityComponentIdPair( - AZ::EntityComponentIdPair(entityId, transformComponentId)); + manipulators.AddEntityComponentIdPair(AZ::EntityComponentIdPair(entityId, transformComponentId)); m_entityIdManipulators.m_lookups.insert_key(entityId); } } @@ -1754,8 +1679,7 @@ namespace AzToolsFramework CreateEntityManipulatorDeselectCommand(undoBatch); } - auto selectionCommand = - AZStd::make_unique(nextEntityIds, s_entityDeselectUndoRedoDesc); + auto selectionCommand = AZStd::make_unique(nextEntityIds, s_entityDeselectUndoRedoDesc); selectionCommand->SetParent(undoBatch.GetUndoBatch()); selectionCommand.release(); @@ -1785,8 +1709,7 @@ namespace AzToolsFramework return false; } - bool EditorTransformComponentSelection::HandleMouseInteraction( - const ViewportInteraction::MouseInteractionEvent& mouseInteraction) + bool EditorTransformComponentSelection::HandleMouseInteraction(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -1816,17 +1739,15 @@ namespace AzToolsFramework } AZ::Transform worldFromLocal; - AZ::TransformBus::EventResult( - worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM); + AZ::TransformBus::EventResult(worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM); const AZ::Vector3 boxPosition = worldFromLocal.TransformPoint(CalculateCenterOffset(entityId, m_pivotMode)); - const AZ::Vector3 scaledSize = AZ::Vector3(s_pivotSize) * - CalculateScreenToWorldMultiplier(worldFromLocal.GetTranslation(), cameraState); + const AZ::Vector3 scaledSize = + AZ::Vector3(s_pivotSize) * CalculateScreenToWorldMultiplier(worldFromLocal.GetTranslation(), cameraState); if (AabbIntersectMouseRay( - mouseInteraction.m_mouseInteraction, - AZ::Aabb::CreateFromMinMax(boxPosition - scaledSize, boxPosition + scaledSize))) + mouseInteraction.m_mouseInteraction, AZ::Aabb::CreateFromMinMax(boxPosition - scaledSize, boxPosition + scaledSize))) { m_cachedEntityIdUnderCursor = entityId; } @@ -1834,16 +1755,15 @@ namespace AzToolsFramework const AZ::EntityId entityIdUnderCursor = m_cachedEntityIdUnderCursor; - EditorContextMenuUpdate( - m_contextMenu, mouseInteraction); + EditorContextMenuUpdate(m_contextMenu, mouseInteraction); m_boxSelect.HandleMouseInteraction(mouseInteraction); if (Input::CycleManipulator(mouseInteraction)) { const size_t scrollBound = 2; - const auto nextMode = (static_cast(m_mode) + scrollBound + - (MouseWheelDelta(mouseInteraction) < 0.0f ? 1 : -1)) % scrollBound; + const auto nextMode = + (static_cast(m_mode) + scrollBound + (MouseWheelDelta(mouseInteraction) < 0.0f ? 1 : -1)) % scrollBound; SetTransformMode(static_cast(nextMode)); @@ -1883,8 +1803,7 @@ namespace AzToolsFramework if (entityIdUnderCursor.IsValid()) { AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity(); - AZ::TransformBus::EventResult( - worldFromLocal, entityIdUnderCursor, &AZ::TransformBus::Events::GetWorldTM); + AZ::TransformBus::EventResult(worldFromLocal, entityIdUnderCursor, &AZ::TransformBus::Events::GetWorldTM); switch (m_mode) { @@ -1912,8 +1831,7 @@ namespace AzToolsFramework if (entityIdUnderCursor.IsValid()) { AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity(); - AZ::TransformBus::EventResult( - worldFromLocal, entityIdUnderCursor, &AZ::TransformBus::Events::GetWorldTM); + AZ::TransformBus::EventResult(worldFromLocal, entityIdUnderCursor, &AZ::TransformBus::Events::GetWorldTM); switch (m_mode) { @@ -1938,15 +1856,14 @@ namespace AzToolsFramework // try snapping to the terrain (if in Translation mode) and entity wasn't picked if (Input::SnapTerrain(mouseInteraction)) { - for(AZ::EntityId entityId : m_selectedEntityIds) + for (AZ::EntityId entityId : m_selectedEntityIds) { ScopedUndoBatch::MarkEntityDirty(entityId); } if (m_mode == Mode::Translation) { - const AZ::Vector3 finalSurfacePosition = - PickTerrainPosition(mouseInteraction.m_mouseInteraction); + const AZ::Vector3 finalSurfacePosition = PickTerrainPosition(mouseInteraction.m_mouseInteraction); // handle modifier alternatives if (Input::IndividualDitto(mouseInteraction)) @@ -1958,7 +1875,7 @@ namespace AzToolsFramework CopyTranslationToSelectedEntitiesGroup(finalSurfacePosition); } } - else if(m_mode == Mode::Rotation) + else if (m_mode == Mode::Rotation) { // handle modifier alternatives if (Input::IndividualDitto(mouseInteraction)) @@ -1981,14 +1898,13 @@ namespace AzToolsFramework { ScopedUndoBatch undoBatch(s_dittoManipulatorUndoRedoDesc); - auto manipulatorCommand = AZStd::make_unique( - CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); + auto manipulatorCommand = + AZStd::make_unique(CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); if (entityIdUnderCursor.IsValid()) { AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity(); - AZ::TransformBus::EventResult( - worldFromLocal, entityIdUnderCursor, &AZ::TransformBus::Events::GetWorldTM); + AZ::TransformBus::EventResult(worldFromLocal, entityIdUnderCursor, &AZ::TransformBus::Events::GetWorldTM); // set orientation/translation to match picked entity switch (m_mode) @@ -2029,13 +1945,9 @@ namespace AzToolsFramework DelegateClearManipulatorOverride(); } - manipulatorCommand->SetManipulatorAfter( - EntityManipulatorCommand::State( - BuildPivotOverride( - m_pivotOverrideFrame.HasTranslationOverride(), - m_pivotOverrideFrame.HasOrientationOverride()), - m_entityIdManipulators.m_manipulators->GetLocalTransform(), - entityIdUnderCursor)); + manipulatorCommand->SetManipulatorAfter(EntityManipulatorCommand::State( + BuildPivotOverride(m_pivotOverrideFrame.HasTranslationOverride(), m_pivotOverrideFrame.HasOrientationOverride()), + m_entityIdManipulators.m_manipulators->GetLocalTransform(), entityIdUnderCursor)); manipulatorCommand->SetParent(undoBatch.GetUndoBatch()); manipulatorCommand.release(); @@ -2073,9 +1985,7 @@ namespace AzToolsFramework QObject::connect(actions.back().get(), &QAction::triggered, actions.back().get(), callback); - EditorActionRequestBus::Broadcast( - &EditorActionRequests::AddActionViaBus, - actionId, actions.back().get()); + EditorActionRequestBus::Broadcast(&EditorActionRequests::AddActionViaBus, actionId, actions.back().get()); } void EditorTransformComponentSelection::OnEscape() @@ -2090,18 +2000,17 @@ namespace AzToolsFramework AZ::ComponentApplicationBus::Broadcast( &AZ::ComponentApplicationRequests::EnumerateEntities, [&func](const AZ::Entity* entity) - { - const AZ::EntityId entityId = entity->GetId(); + { + const AZ::EntityId entityId = entity->GetId(); - bool editorEntity = false; - EditorEntityContextRequestBus::BroadcastResult( - editorEntity, &EditorEntityContextRequests::IsEditorEntity, entityId); + bool editorEntity = false; + EditorEntityContextRequestBus::BroadcastResult(editorEntity, &EditorEntityContextRequests::IsEditorEntity, entityId); - if (editorEntity) - { - func(entityId); - } - }); + if (editorEntity) + { + func(entityId); + } + }); } void EditorTransformComponentSelection::DelegateClearManipulatorOverride() @@ -2149,22 +2058,22 @@ namespace AzToolsFramework }; // lock selection - AddAction(m_actions, { QKeySequence(Qt::Key_L) }, - /*ID_EDIT_FREEZE =*/ 32900, - s_lockSelectionTitle, s_lockSelectionDesc, + AddAction( + m_actions, { QKeySequence(Qt::Key_L) }, + /*ID_EDIT_FREEZE =*/32900, s_lockSelectionTitle, s_lockSelectionDesc, [lockUnlock]() - { - lockUnlock(true); - }); + { + lockUnlock(true); + }); // unlock selection - AddAction(m_actions, { QKeySequence(Qt::CTRL + Qt::Key_L) }, - /*ID_EDIT_UNFREEZE =*/ 32973, - s_lockSelectionTitle, s_lockSelectionDesc, + AddAction( + m_actions, { QKeySequence(Qt::CTRL + Qt::Key_L) }, + /*ID_EDIT_UNFREEZE =*/32973, s_lockSelectionTitle, s_lockSelectionDesc, [lockUnlock]() - { - lockUnlock(false); - }); + { + lockUnlock(false); + }); const auto showHide = [this](const bool show) { @@ -2189,144 +2098,147 @@ namespace AzToolsFramework }; // hide selection - AddAction(m_actions, { QKeySequence(Qt::Key_H) }, - /*ID_EDIT_HIDE =*/ 32898, - s_hideSelectionTitle, s_hideSelectionDesc, + AddAction( + m_actions, { QKeySequence(Qt::Key_H) }, + /*ID_EDIT_HIDE =*/32898, s_hideSelectionTitle, s_hideSelectionDesc, [showHide]() - { - showHide(false); - }); + { + showHide(false); + }); // show selection - AddAction(m_actions, { QKeySequence(Qt::CTRL + Qt::Key_H) }, - /*ID_EDIT_UNHIDE =*/ 32974, - s_hideSelectionTitle, s_hideSelectionDesc, + AddAction( + m_actions, { QKeySequence(Qt::CTRL + Qt::Key_H) }, + /*ID_EDIT_UNHIDE =*/32974, s_hideSelectionTitle, s_hideSelectionDesc, [showHide]() - { - showHide(true); - }); + { + showHide(true); + }); // unlock all entities in the level/scene - AddAction(m_actions, { QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_L) }, - /*ID_EDIT_UNFREEZEALL =*/ 32901, - s_unlockAllTitle, s_unlockAllDesc, + AddAction( + m_actions, { QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_L) }, + /*ID_EDIT_UNFREEZEALL =*/32901, s_unlockAllTitle, s_unlockAllDesc, []() - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); + { + AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); - ScopedUndoBatch undoBatch(s_unlockAllUndoRedoDesc); + ScopedUndoBatch undoBatch(s_unlockAllUndoRedoDesc); - EnumerateEditorEntities([](AZ::EntityId entityId) - { - ScopedUndoBatch::MarkEntityDirty(entityId); - SetEntityLockState(entityId, false); + EnumerateEditorEntities( + [](AZ::EntityId entityId) + { + ScopedUndoBatch::MarkEntityDirty(entityId); + SetEntityLockState(entityId, false); + }); }); - }); // show all entities in the level/scene - AddAction(m_actions, { QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_H) }, - /*ID_EDIT_UNHIDEALL =*/ 32899, - s_showAllTitle, s_showAllDesc, + AddAction( + m_actions, { QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_H) }, + /*ID_EDIT_UNHIDEALL =*/32899, s_showAllTitle, s_showAllDesc, []() - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); + { + AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); - ScopedUndoBatch undoBatch(s_showAllEntitiesUndoRedoDesc); + ScopedUndoBatch undoBatch(s_showAllEntitiesUndoRedoDesc); - EnumerateEditorEntities([](AZ::EntityId entityId) - { - ScopedUndoBatch::MarkEntityDirty(entityId); - SetEntityVisibility(entityId, true); + EnumerateEditorEntities( + [](AZ::EntityId entityId) + { + ScopedUndoBatch::MarkEntityDirty(entityId); + SetEntityVisibility(entityId, true); + }); }); - }); // select all entities in the level/scene - AddAction(m_actions, { QKeySequence(Qt::CTRL + Qt::Key_A) }, - /*ID_EDIT_SELECTALL =*/ 33376, - s_selectAllTitle, s_selectAllDesc, + AddAction( + m_actions, { QKeySequence(Qt::CTRL + Qt::Key_A) }, + /*ID_EDIT_SELECTALL =*/33376, s_selectAllTitle, s_selectAllDesc, [this]() - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); - - ScopedUndoBatch undoBatch(s_selectAllEntitiesUndoRedoDesc); - - if (m_entityIdManipulators.m_manipulators) { - auto manipulatorCommand = AZStd::make_unique( - CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); - - // note, nothing will change that the manipulatorCommand needs to keep track - // for after so no need to call SetManipulatorAfter + AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); - manipulatorCommand->SetParent(undoBatch.GetUndoBatch()); - manipulatorCommand.release(); - } + ScopedUndoBatch undoBatch(s_selectAllEntitiesUndoRedoDesc); - EnumerateEditorEntities([this](AZ::EntityId entityId) - { - if (IsSelectableInViewport(entityId)) + if (m_entityIdManipulators.m_manipulators) { - AddEntityToSelection(entityId); + auto manipulatorCommand = + AZStd::make_unique(CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); + + // note, nothing will change that the manipulatorCommand needs to keep track + // for after so no need to call SetManipulatorAfter + + manipulatorCommand->SetParent(undoBatch.GetUndoBatch()); + manipulatorCommand.release(); } - }); - auto nextEntityIds = EntityIdVectorFromContainer(m_selectedEntityIds); + EnumerateEditorEntities( + [this](AZ::EntityId entityId) + { + if (IsSelectableInViewport(entityId)) + { + AddEntityToSelection(entityId); + } + }); - auto selectionCommand = AZStd::make_unique( - nextEntityIds, s_selectAllEntitiesUndoRedoDesc); - selectionCommand->SetParent(undoBatch.GetUndoBatch()); - selectionCommand.release(); + auto nextEntityIds = EntityIdVectorFromContainer(m_selectedEntityIds); - SetSelectedEntities(nextEntityIds); - RegenerateManipulators(); - }); + auto selectionCommand = AZStd::make_unique(nextEntityIds, s_selectAllEntitiesUndoRedoDesc); + selectionCommand->SetParent(undoBatch.GetUndoBatch()); + selectionCommand.release(); + + SetSelectedEntities(nextEntityIds); + RegenerateManipulators(); + }); // invert current selection - AddAction(m_actions, { QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_I) }, - /*ID_EDIT_INVERTSELECTION =*/ 33692, - s_invertSelectionTitle, s_invertSelectionDesc, + AddAction( + m_actions, { QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_I) }, + /*ID_EDIT_INVERTSELECTION =*/33692, s_invertSelectionTitle, s_invertSelectionDesc, [this]() - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); + { + AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); - ScopedUndoBatch undoBatch(s_invertSelectionUndoRedoDesc); + ScopedUndoBatch undoBatch(s_invertSelectionUndoRedoDesc); - if (m_entityIdManipulators.m_manipulators) - { - auto manipulatorCommand = AZStd::make_unique( - CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); + if (m_entityIdManipulators.m_manipulators) + { + auto manipulatorCommand = + AZStd::make_unique(CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); - // note, nothing will change that the manipulatorCommand needs to keep track - // for after so no need to call SetManipulatorAfter + // note, nothing will change that the manipulatorCommand needs to keep track + // for after so no need to call SetManipulatorAfter - manipulatorCommand->SetParent(undoBatch.GetUndoBatch()); - manipulatorCommand.release(); - } + manipulatorCommand->SetParent(undoBatch.GetUndoBatch()); + manipulatorCommand.release(); + } - EntityIdSet entityIds; - EnumerateEditorEntities([this, &entityIds](AZ::EntityId entityId) - { - const auto entityIdIt = AZStd::find(m_selectedEntityIds.begin(), m_selectedEntityIds.end(), entityId); - if (entityIdIt == m_selectedEntityIds.end()) - { - if (IsSelectableInViewport(entityId)) + EntityIdSet entityIds; + EnumerateEditorEntities( + [this, &entityIds](AZ::EntityId entityId) { - entityIds.insert(entityId); - } - } - }); + const auto entityIdIt = AZStd::find(m_selectedEntityIds.begin(), m_selectedEntityIds.end(), entityId); + if (entityIdIt == m_selectedEntityIds.end()) + { + if (IsSelectableInViewport(entityId)) + { + entityIds.insert(entityId); + } + } + }); - m_selectedEntityIds = entityIds; + m_selectedEntityIds = entityIds; - auto nextEntityIds = EntityIdVectorFromContainer(entityIds); + auto nextEntityIds = EntityIdVectorFromContainer(entityIds); - auto selectionCommand = AZStd::make_unique(nextEntityIds, s_invertSelectionUndoRedoDesc); - selectionCommand->SetParent(undoBatch.GetUndoBatch()); - selectionCommand.release(); + auto selectionCommand = AZStd::make_unique(nextEntityIds, s_invertSelectionUndoRedoDesc); + selectionCommand->SetParent(undoBatch.GetUndoBatch()); + selectionCommand.release(); - SetSelectedEntities(nextEntityIds); - RegenerateManipulators(); - }); + SetSelectedEntities(nextEntityIds); + RegenerateManipulators(); + }); bool isPrefabSystemEnabled = false; AzFramework::ApplicationRequests::Bus::BroadcastResult( @@ -2340,8 +2252,10 @@ namespace AzToolsFramework { // duplicate selection AddAction( - m_actions, {QKeySequence(Qt::CTRL + Qt::Key_D)}, - /*ID_EDIT_CLONE =*/33525, s_duplicateTitle, s_duplicateDesc, []() { + m_actions, { QKeySequence(Qt::CTRL + Qt::Key_D) }, + /*ID_EDIT_CLONE =*/33525, s_duplicateTitle, s_duplicateDesc, + []() + { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); // Clear Widget selection - Prevents issues caused by cloning entities while a property in the Reflected Property Editor @@ -2366,121 +2280,113 @@ namespace AzToolsFramework // delete selection AddAction( m_actions, { QKeySequence(Qt::Key_Delete) }, - /*ID_EDIT_DELETE=*/ 33480, - s_deleteTitle, s_deleteDesc, + /*ID_EDIT_DELETE=*/33480, s_deleteTitle, s_deleteDesc, [this]() - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); + { + AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); - ScopedUndoBatch undoBatch(s_deleteUndoRedoDesc); + ScopedUndoBatch undoBatch(s_deleteUndoRedoDesc); - CreateEntityManipulatorDeselectCommand(undoBatch); + CreateEntityManipulatorDeselectCommand(undoBatch); - ToolsApplicationRequestBus::Broadcast( - &ToolsApplicationRequests::DeleteEntitiesAndAllDescendants, - EntityIdVectorFromContainer(m_selectedEntityIds)); + ToolsApplicationRequestBus::Broadcast( + &ToolsApplicationRequests::DeleteEntitiesAndAllDescendants, EntityIdVectorFromContainer(m_selectedEntityIds)); - m_selectedEntityIds.clear(); - m_pivotOverrideFrame.Reset(); - }); + m_selectedEntityIds.clear(); + m_pivotOverrideFrame.Reset(); + }); AddAction( m_actions, { QKeySequence(Qt::Key_Space) }, - /*ID_EDIT_ESCAPE=*/ 33513, - "", "", + /*ID_EDIT_ESCAPE=*/33513, "", "", [this]() - { - DeselectEntities(); - }); + { + DeselectEntities(); + }); AddAction( m_actions, { QKeySequence(Qt::Key_P) }, - /*ID_EDIT_PIVOT=*/ 36203, - s_togglePivotTitleEditMenu, s_togglePivotDesc, + /*ID_EDIT_PIVOT=*/36203, s_togglePivotTitleEditMenu, s_togglePivotDesc, [this]() - { - ToggleCenterPivotSelection(); - }); + { + ToggleCenterPivotSelection(); + }); AddAction( m_actions, { QKeySequence(Qt::Key_R) }, - /*ID_EDIT_RESET=*/ 36204, - s_resetEntityTransformTitle, s_resetEntityTransformDesc, + /*ID_EDIT_RESET=*/36204, s_resetEntityTransformTitle, s_resetEntityTransformDesc, [this]() - { - switch (m_mode) { - case Mode::Rotation: - ResetOrientationForSelectedEntitiesLocal(); - break; - case Mode::Scale: - CopyScaleToSelectedEntitiesIndividualLocal(1.0f); - break; - case Mode::Translation: - ResetTranslationForSelectedEntitiesLocal(); - break; - } - }); + switch (m_mode) + { + case Mode::Rotation: + ResetOrientationForSelectedEntitiesLocal(); + break; + case Mode::Scale: + CopyScaleToSelectedEntitiesIndividualLocal(1.0f); + break; + case Mode::Translation: + ResetTranslationForSelectedEntitiesLocal(); + break; + } + }); AddAction( m_actions, { QKeySequence(Qt::CTRL + Qt::Key_R) }, - /*ID_EDIT_RESET_MANIPULATOR=*/ 36207, - s_resetManipulatorTitle, s_resetManipulatorDesc, + /*ID_EDIT_RESET_MANIPULATOR=*/36207, s_resetManipulatorTitle, s_resetManipulatorDesc, AZStd::bind(AZStd::mem_fn(&EditorTransformComponentSelection::DelegateClearManipulatorOverride), this)); AddAction( m_actions, { QKeySequence(Qt::ALT + Qt::Key_R) }, - /*ID_EDIT_RESET_LOCAL=*/ 36205, - s_resetTransformLocalTitle, s_resetTransformLocalDesc, + /*ID_EDIT_RESET_LOCAL=*/36205, s_resetTransformLocalTitle, s_resetTransformLocalDesc, [this]() - { - switch (m_mode) { - case Mode::Rotation: - ResetOrientationForSelectedEntitiesLocal(); - break; - case Mode::Scale: - CopyScaleToSelectedEntitiesIndividualWorld(1.0f); - break; - case Mode::Translation: - // do nothing - break; - } - }); + switch (m_mode) + { + case Mode::Rotation: + ResetOrientationForSelectedEntitiesLocal(); + break; + case Mode::Scale: + CopyScaleToSelectedEntitiesIndividualWorld(1.0f); + break; + case Mode::Translation: + // do nothing + break; + } + }); AddAction( m_actions, { QKeySequence(Qt::SHIFT + Qt::Key_R) }, - /*ID_EDIT_RESET_WORLD=*/ 36206, - s_resetTransformWorldTitle, s_resetTransformWorldDesc, + /*ID_EDIT_RESET_WORLD=*/36206, s_resetTransformWorldTitle, s_resetTransformWorldDesc, [this]() - { - switch (m_mode) { - case Mode::Rotation: + switch (m_mode) { - // begin an undo batch so operations inside CopyOrientation... and - // DelegateClear... are grouped into a single undo/redo - ScopedUndoBatch undoBatch { s_resetTransformWorldTitle }; - CopyOrientationToSelectedEntitiesIndividual(AZ::Quaternion::CreateIdentity()); - ClearManipulatorOrientationOverride(); + case Mode::Rotation: + { + // begin an undo batch so operations inside CopyOrientation... and + // DelegateClear... are grouped into a single undo/redo + ScopedUndoBatch undoBatch{ s_resetTransformWorldTitle }; + CopyOrientationToSelectedEntitiesIndividual(AZ::Quaternion::CreateIdentity()); + ClearManipulatorOrientationOverride(); + } + break; + case Mode::Scale: + case Mode::Translation: + break; } - break; - case Mode::Scale: - case Mode::Translation: - break; - } - }); - + }); + AddAction( m_actions, { QKeySequence(Qt::Key_U) }, /*ID_VIEWPORTUI_VISIBLE=*/50040, "Toggle ViewportUI", "Hide/Unhide Viewport UI", - [this]() - { + [this]() + { SetViewportUiClusterVisible(m_transformModeClusterId, !m_viewportUiVisible); SetViewportUiClusterVisible(m_spaceCluster.m_spaceClusterId, !m_viewportUiVisible); m_viewportUiVisible = !m_viewportUiVisible; - }); - + }); + EditorMenuRequestBus::Broadcast(&EditorMenuRequests::RestoreEditMenuToDefault); } @@ -2488,8 +2394,7 @@ namespace AzToolsFramework { for (auto& action : m_actions) { - EditorActionRequestBus::Broadcast( - &EditorActionRequests::RemoveActionViaBus, action.get()); + EditorActionRequestBus::Broadcast(&EditorActionRequests::RemoveActionViaBus, action.get()); } m_actions.clear(); @@ -2558,42 +2463,37 @@ namespace AzToolsFramework { // create the cluster for changing transform mode ViewportUi::ViewportUiRequestBus::EventResult( - m_transformModeClusterId, ViewportUi::DefaultViewportId, - &ViewportUi::ViewportUiRequestBus::Events::CreateCluster, ViewportUi::Alignment::TopLeft); + m_transformModeClusterId, ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateCluster, + ViewportUi::Alignment::TopLeft); // create and register the buttons (strings correspond to icons even if the values appear different) m_translateButtonId = RegisterClusterButton(m_transformModeClusterId, "Move"); m_rotateButtonId = RegisterClusterButton(m_transformModeClusterId, "Translate"); m_scaleButtonId = RegisterClusterButton(m_transformModeClusterId, "Scale"); - auto onButtonClicked = - [this](ViewportUi::ButtonId buttonId) + auto onButtonClicked = [this](ViewportUi::ButtonId buttonId) + { + if (buttonId == m_translateButtonId) { - if (buttonId == m_translateButtonId) - { - SetTransformMode(Mode::Translation); - } - else if (buttonId == m_rotateButtonId) - { - SetTransformMode(Mode::Rotation); - } - else if (buttonId == m_scaleButtonId) - { - SetTransformMode(Mode::Scale); - } - }; + SetTransformMode(Mode::Translation); + } + else if (buttonId == m_rotateButtonId) + { + SetTransformMode(Mode::Rotation); + } + else if (buttonId == m_scaleButtonId) + { + SetTransformMode(Mode::Scale); + } + }; m_transformModeSelectionHandler = AZ::Event::Handler(onButtonClicked); ViewportUi::ViewportUiRequestBus::Event( - ViewportUi::DefaultViewportId, - &ViewportUi::ViewportUiRequestBus::Events::SetClusterActiveButton, - m_transformModeClusterId, + ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::SetClusterActiveButton, m_transformModeClusterId, m_translateButtonId); ViewportUi::ViewportUiRequestBus::Event( - ViewportUi::DefaultViewportId, - &ViewportUi::ViewportUiRequestBus::Events::RegisterClusterEventHandler, - m_transformModeClusterId, + ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::RegisterClusterEventHandler, m_transformModeClusterId, m_transformModeSelectionHandler); } @@ -2609,7 +2509,8 @@ namespace AzToolsFramework m_spaceCluster.m_parentButtonId = RegisterClusterButton(m_spaceCluster.m_spaceClusterId, "Parent"); m_spaceCluster.m_localButtonId = RegisterClusterButton(m_spaceCluster.m_spaceClusterId, "Local"); - auto onButtonClicked = [this](ViewportUi::ButtonId buttonId) { + auto onButtonClicked = [this](ViewportUi::ButtonId buttonId) + { if (buttonId == m_spaceCluster.m_localButtonId) { // Unlock @@ -2674,14 +2575,13 @@ namespace AzToolsFramework if (m_pivotOverrideFrame.m_orientationOverride && m_entityIdManipulators.m_manipulators) { - m_pivotOverrideFrame.m_orientationOverride = QuaternionFromTransformNoScaling( - m_entityIdManipulators.m_manipulators->GetLocalTransform()); + m_pivotOverrideFrame.m_orientationOverride = + QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()); } if (m_pivotOverrideFrame.m_translationOverride && m_entityIdManipulators.m_manipulators) { - m_pivotOverrideFrame.m_translationOverride = - m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); + m_pivotOverrideFrame.m_translationOverride = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); } m_mode = mode; @@ -2758,8 +2658,7 @@ namespace AzToolsFramework // we are responsible for updating the current selection m_didSetSelectedEntities = true; - ToolsApplicationRequestBus::Broadcast( - &ToolsApplicationRequests::SetSelectedEntities, entityIds); + ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, entityIds); } void EditorTransformComponentSelection::RefreshManipulators(const RefreshType refreshType) @@ -2779,15 +2678,13 @@ namespace AzToolsFramework break; case RefreshType::Orientation: transform = AZ::Transform::CreateFromQuaternionAndTranslation( - RecalculateAverageManipulatorOrientation( - m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_referenceFrame), + RecalculateAverageManipulatorOrientation(m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_referenceFrame), m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation()); break; case RefreshType::Translation: transform = AZ::Transform::CreateFromQuaternionAndTranslation( m_entityIdManipulators.m_manipulators->GetLocalTransform().GetRotation(), - RecalculateAverageManipulatorTranslation( - m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode)); + RecalculateAverageManipulatorTranslation(m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode)); break; } @@ -2810,9 +2707,8 @@ namespace AzToolsFramework if (m_entityIdManipulators.m_manipulators) { - m_entityIdManipulators.m_manipulators->SetLocalTransform( - AZ::Transform::CreateFromQuaternionAndTranslation( - orientation, m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation())); + m_entityIdManipulators.m_manipulators->SetLocalTransform(AZ::Transform::CreateFromQuaternionAndTranslation( + orientation, m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation())); m_entityIdManipulators.m_manipulators->SetBoundsDirty(); } @@ -2839,15 +2735,14 @@ namespace AzToolsFramework { ScopedUndoBatch undoBatch(s_resetManipulatorTranslationUndoRedoDesc); - auto manipulatorCommand = AZStd::make_unique( - CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); + auto manipulatorCommand = + AZStd::make_unique(CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); m_pivotOverrideFrame.ResetPickedTranslation(); m_pivotOverrideFrame.m_pickedEntityIdOverride.SetInvalid(); - m_entityIdManipulators.m_manipulators->SetLocalTransform( - RecalculateAverageManipulatorTransform( - m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode, m_referenceFrame)); + m_entityIdManipulators.m_manipulators->SetLocalTransform(RecalculateAverageManipulatorTransform( + m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode, m_referenceFrame)); m_entityIdManipulators.m_manipulators->SetBoundsDirty(); @@ -2864,20 +2759,18 @@ namespace AzToolsFramework if (m_entityIdManipulators.m_manipulators) { - ScopedUndoBatch undoBatch { s_resetManipulatorOrientationUndoRedoDesc }; + ScopedUndoBatch undoBatch{ s_resetManipulatorOrientationUndoRedoDesc }; - auto manipulatorCommand = AZStd::make_unique( - CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); + auto manipulatorCommand = + AZStd::make_unique(CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); m_pivotOverrideFrame.ResetPickedOrientation(); m_pivotOverrideFrame.m_pickedEntityIdOverride.SetInvalid(); // parent reference frame is the default (when no modifiers are held) - m_entityIdManipulators.m_manipulators->SetLocalTransform( - AZ::Transform::CreateFromQuaternionAndTranslation( - ETCS::CalculatePivotOrientationForEntityIds( - m_entityIdManipulators.m_lookups, ReferenceFrame::Parent).m_worldOrientation, - m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation())); + m_entityIdManipulators.m_manipulators->SetLocalTransform(AZ::Transform::CreateFromQuaternionAndTranslation( + ETCS::CalculatePivotOrientationForEntityIds(m_entityIdManipulators.m_lookups, ReferenceFrame::Parent).m_worldOrientation, + m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation())); m_entityIdManipulators.m_manipulators->SetBoundsDirty(); @@ -2900,8 +2793,7 @@ namespace AzToolsFramework { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); - static_assert(AZStd::is_same::value, - "Container key type is not an EntityId"); + static_assert(AZStd::is_same::value, "Container key type is not an EntityId"); AZ::EntityId parentId; AZ::TransformBus::EventResult(parentId, entityId, &AZ::TransformBus::Events::GetParentId); @@ -2935,11 +2827,10 @@ namespace AzToolsFramework ScopedUndoBatch undoBatch(s_dittoTranslationGroupUndoRedoDesc); // store previous translation manipulator position - const AZ::Vector3 previousPivotTranslation = - m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); + const AZ::Vector3 previousPivotTranslation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); - auto manipulatorCommand = AZStd::make_unique( - CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); + auto manipulatorCommand = + AZStd::make_unique(CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); // refresh the transform pivot override if it's set if (m_pivotOverrideFrame.m_translationOverride) @@ -2947,15 +2838,11 @@ namespace AzToolsFramework OverrideManipulatorTranslation(translation); } - manipulatorCommand->SetManipulatorAfter( - EntityManipulatorCommand::State( - BuildPivotOverride( - m_pivotOverrideFrame.HasTranslationOverride(), - m_pivotOverrideFrame.HasOrientationOverride()), - AZ::Transform::CreateFromQuaternionAndTranslation( - QuaternionFromTransformNoScaling( - m_entityIdManipulators.m_manipulators->GetLocalTransform()), translation), - m_pivotOverrideFrame.m_pickedEntityIdOverride)); + manipulatorCommand->SetManipulatorAfter(EntityManipulatorCommand::State( + BuildPivotOverride(m_pivotOverrideFrame.HasTranslationOverride(), m_pivotOverrideFrame.HasOrientationOverride()), + AZ::Transform::CreateFromQuaternionAndTranslation( + QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()), translation), + m_pivotOverrideFrame.m_pickedEntityIdOverride)); manipulatorCommand->SetParent(undoBatch.GetUndoBatch()); manipulatorCommand.release(); @@ -2995,8 +2882,8 @@ namespace AzToolsFramework { ScopedUndoBatch undoBatch(s_dittoTranslationIndividualUndoRedoDesc); - auto manipulatorCommand = AZStd::make_unique( - CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); + auto manipulatorCommand = + AZStd::make_unique(CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); // refresh the transform pivot override if it's set if (m_pivotOverrideFrame.m_translationOverride) @@ -3004,15 +2891,11 @@ namespace AzToolsFramework OverrideManipulatorTranslation(translation); } - manipulatorCommand->SetManipulatorAfter( - EntityManipulatorCommand::State( - BuildPivotOverride( - m_pivotOverrideFrame.HasTranslationOverride(), - m_pivotOverrideFrame.HasOrientationOverride()), - AZ::Transform::CreateFromQuaternionAndTranslation( - QuaternionFromTransformNoScaling( - m_entityIdManipulators.m_manipulators->GetLocalTransform()), translation), - m_pivotOverrideFrame.m_pickedEntityIdOverride)); + manipulatorCommand->SetManipulatorAfter(EntityManipulatorCommand::State( + BuildPivotOverride(m_pivotOverrideFrame.HasTranslationOverride(), m_pivotOverrideFrame.HasOrientationOverride()), + AZ::Transform::CreateFromQuaternionAndTranslation( + QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()), translation), + m_pivotOverrideFrame.m_pickedEntityIdOverride)); manipulatorCommand->SetParent(undoBatch.GetUndoBatch()); manipulatorCommand.release(); @@ -3084,17 +2967,16 @@ namespace AzToolsFramework RefreshUiAfterChange(manipulatorEntityIds.m_entityIds); } - void EditorTransformComponentSelection::CopyOrientationToSelectedEntitiesIndividual( - const AZ::Quaternion& orientation) + void EditorTransformComponentSelection::CopyOrientationToSelectedEntitiesIndividual(const AZ::Quaternion& orientation) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); if (m_entityIdManipulators.m_manipulators) { - ScopedUndoBatch undoBatch { s_dittoEntityOrientationIndividualUndoRedoDesc }; + ScopedUndoBatch undoBatch{ s_dittoEntityOrientationIndividualUndoRedoDesc }; - auto manipulatorCommand = AZStd::make_unique( - CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); + auto manipulatorCommand = + AZStd::make_unique(CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); ManipulatorEntityIds manipulatorEntityIds; BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds.m_entityIds); @@ -3130,8 +3012,7 @@ namespace AzToolsFramework } } - void EditorTransformComponentSelection::CopyOrientationToSelectedEntitiesGroup( - const AZ::Quaternion& orientation) + void EditorTransformComponentSelection::CopyOrientationToSelectedEntitiesGroup(const AZ::Quaternion& orientation) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -3139,8 +3020,8 @@ namespace AzToolsFramework { ScopedUndoBatch undoBatch(s_dittoEntityOrientationGroupUndoRedoDesc); - auto manipulatorCommand = AZStd::make_unique( - CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); + auto manipulatorCommand = + AZStd::make_unique(CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); ManipulatorEntityIds manipulatorEntityIds; BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds.m_entityIds); @@ -3148,8 +3029,7 @@ namespace AzToolsFramework // save initial transforms const auto transformsBefore = RecordTransformsBefore(manipulatorEntityIds.m_entityIds); - const AZ::Transform currentTransform = - m_entityIdManipulators.m_manipulators->GetLocalTransform(); + const AZ::Transform currentTransform = m_entityIdManipulators.m_manipulators->GetLocalTransform(); const AZ::Transform nextTransform = AZ::Transform::CreateFromQuaternionAndTranslation( orientation, m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation()); @@ -3163,8 +3043,7 @@ namespace AzToolsFramework const auto transformIt = transformsBefore.find(entityId); if (transformIt != transformsBefore.end()) { - const AZ::Transform transformInPivotSpace = - currentTransform.GetInverse() * transformIt->second; + const AZ::Transform transformInPivotSpace = currentTransform.GetInverse() * transformIt->second; SetEntityWorldTransform(entityId, nextTransform * transformInPivotSpace); } @@ -3186,7 +3065,7 @@ namespace AzToolsFramework AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); ScopedUndoBatch undoBatch(s_resetOrientationToParentUndoRedoDesc); - for (const auto& entityIdLookup: m_entityIdManipulators.m_lookups) + for (const auto& entityIdLookup : m_entityIdManipulators.m_lookups) { ScopedUndoBatch::MarkEntityDirty(entityIdLookup.first); SetEntityLocalRotation(entityIdLookup.first, AZ::Vector3::CreateZero()); @@ -3209,14 +3088,12 @@ namespace AzToolsFramework ScopedUndoBatch undoBatch(s_resetTranslationToParentUndoRedoDesc); ManipulatorEntityIds manipulatorEntityIds; - BuildSortedEntityIdVectorFromEntityIdMap( - m_entityIdManipulators.m_lookups, manipulatorEntityIds.m_entityIds); + BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds.m_entityIds); for (AZ::EntityId entityId : manipulatorEntityIds.m_entityIds) { AZ::EntityId parentId; - AZ::TransformBus::EventResult( - parentId, entityId, &AZ::TransformBus::Events::GetParentId); + AZ::TransformBus::EventResult(parentId, entityId, &AZ::TransformBus::Events::GetParentId); if (parentId.IsValid()) { @@ -3231,11 +3108,15 @@ namespace AzToolsFramework } } - void EditorTransformComponentSelection::PopulateEditorGlobalContextMenu( - QMenu* menu, const AZ::Vector2& /*point*/, const int /*flags*/) + void EditorTransformComponentSelection::PopulateEditorGlobalContextMenu(QMenu* menu, const AZ::Vector2& /*point*/, const int /*flags*/) { QAction* action = menu->addAction(QObject::tr(s_togglePivotTitleRightClick)); - QObject::connect(action, &QAction::triggered, action, [this]() { ToggleCenterPivotSelection(); }); + QObject::connect( + action, &QAction::triggered, action, + [this]() + { + ToggleCenterPivotSelection(); + }); } void EditorTransformComponentSelection::BeforeEntitySelectionChanged() @@ -3281,8 +3162,10 @@ namespace AzToolsFramework } static void DrawPreviewAxis( - AzFramework::DebugDisplayRequests& display, const AZ::Transform& transform, - const float axisLength, const AzFramework::CameraState& cameraState) + AzFramework::DebugDisplayRequests& display, + const AZ::Transform& transform, + const float axisLength, + const AzFramework::CameraState& cameraState) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -3297,8 +3180,8 @@ namespace AzToolsFramework const auto axisFlip = [&transform, &cameraState](const AZ::Vector3& axis) -> float { return ShouldFlipCameraAxis( - AZ::Transform::CreateIdentity(), transform.GetTranslation(), - TransformDirectionNoScaling(transform, axis), cameraState) + AZ::Transform::CreateIdentity(), transform.GetTranslation(), TransformDirectionNoScaling(transform, axis), + cameraState) ? -1.0f : 1.0f; }; @@ -3306,18 +3189,15 @@ namespace AzToolsFramework display.SetColor(s_fadedXAxisColor); display.DrawLine( transform.GetTranslation(), - transform.GetTranslation() + transform.GetBasisX().GetNormalizedSafe() * - axisLength * axisFlip(AZ::Vector3::CreateAxisX())); + transform.GetTranslation() + transform.GetBasisX().GetNormalizedSafe() * axisLength * axisFlip(AZ::Vector3::CreateAxisX())); display.SetColor(s_fadedYAxisColor); display.DrawLine( transform.GetTranslation(), - transform.GetTranslation() + transform.GetBasisY().GetNormalizedSafe() * - axisLength * axisFlip(AZ::Vector3::CreateAxisY())); + transform.GetTranslation() + transform.GetBasisY().GetNormalizedSafe() * axisLength * axisFlip(AZ::Vector3::CreateAxisY())); display.SetColor(s_fadedZAxisColor); display.DrawLine( transform.GetTranslation(), - transform.GetTranslation() + transform.GetBasisZ().GetNormalizedSafe() * - axisLength * axisFlip(AZ::Vector3::CreateAxisZ())); + transform.GetTranslation() + transform.GetBasisZ().GetNormalizedSafe() * axisLength * axisFlip(AZ::Vector3::CreateAxisZ())); display.DepthWriteOn(); display.DepthTestOn(); @@ -3330,15 +3210,11 @@ namespace AzToolsFramework static void DrawManipulatorGrid( AzFramework::DebugDisplayRequests& debugDisplay, const EntityIdManipulators& entityIdManipulators, const float gridSize) { - const AZ::Matrix3x3 orientation = - AZ::Matrix3x3::CreateFromTransform(entityIdManipulators.m_manipulators->GetLocalTransform()); + const AZ::Matrix3x3 orientation = AZ::Matrix3x3::CreateFromTransform(entityIdManipulators.m_manipulators->GetLocalTransform()); - const AZ::Vector3 translation = - entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); + const AZ::Vector3 translation = entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); - DrawSnappingGrid( - debugDisplay, AZ::Transform::CreateFromMatrix3x3AndTranslation(orientation, translation), - gridSize); + DrawSnappingGrid(debugDisplay, AZ::Transform::CreateFromMatrix3x3AndTranslation(orientation, translation), gridSize); } void EditorTransformComponentSelection::DisplayViewportSelection( @@ -3348,16 +3224,14 @@ namespace AzToolsFramework CheckDirtyEntityIds(); - const auto modifiers = ViewportInteraction::KeyboardModifiers( - ViewportInteraction::TranslateKeyboardModifiers(QApplication::queryKeyboardModifiers())); + const auto modifiers = + ViewportInteraction::KeyboardModifiers(ViewportInteraction::TranslateKeyboardModifiers(QApplication::queryKeyboardModifiers())); m_cursorState.Update(); HandleAccents( - !m_selectedEntityIds.empty(), m_cachedEntityIdUnderCursor, - modifiers.Ctrl(), m_hoveredEntityId, - ViewportInteraction::BuildMouseButtons( - QGuiApplication::mouseButtons()), m_boxSelect.Active()); + !m_selectedEntityIds.empty(), m_cachedEntityIdUnderCursor, modifiers.Ctrl(), m_hoveredEntityId, + ViewportInteraction::BuildMouseButtons(QGuiApplication::mouseButtons()), m_boxSelect.Active()); const ReferenceFrame referenceFrame = m_spaceCluster.m_spaceLock.value_or(ReferenceFrameFromModifiers(modifiers)); @@ -3370,10 +3244,8 @@ namespace AzToolsFramework refresh = true; } - refresh = refresh - || (m_triedToRefresh - && m_entityIdManipulators.m_manipulators - && !m_entityIdManipulators.m_manipulators->PerformingAction()); + refresh = refresh || + (m_triedToRefresh && m_entityIdManipulators.m_manipulators && !m_entityIdManipulators.m_manipulators->PerformingAction()); // we've moved from parent to world space, parent to local space or vice versa by holding or // releasing shift and/or alt - make sure we update the manipulator orientation appropriately @@ -3386,8 +3258,7 @@ namespace AzToolsFramework const auto entityFilter = [this](AZ::EntityId entityId) { - const bool entityHasManipulator = - m_entityIdManipulators.m_lookups.find(entityId) != m_entityIdManipulators.m_lookups.end(); + const bool entityHasManipulator = m_entityIdManipulators.m_lookups.find(entityId) != m_entityIdManipulators.m_lookups.end(); return !entityHasManipulator; }; @@ -3398,15 +3269,12 @@ namespace AzToolsFramework { if (m_pivotOverrideFrame.m_pickedEntityIdOverride.IsValid()) { - const AZ::Transform pickedEntityWorldTransform = - AZ::Transform::CreateFromQuaternionAndTranslation( - ETCS::CalculatePivotOrientation( - m_pivotOverrideFrame.m_pickedEntityIdOverride, referenceFrame).m_worldOrientation, - CalculatePivotTranslation( - m_pivotOverrideFrame.m_pickedEntityIdOverride, m_pivotMode)); + const AZ::Transform pickedEntityWorldTransform = AZ::Transform::CreateFromQuaternionAndTranslation( + ETCS::CalculatePivotOrientation(m_pivotOverrideFrame.m_pickedEntityIdOverride, referenceFrame).m_worldOrientation, + CalculatePivotTranslation(m_pivotOverrideFrame.m_pickedEntityIdOverride, m_pivotMode)); - const float scaledSize = s_pivotSize * - CalculateScreenToWorldMultiplier(pickedEntityWorldTransform.GetTranslation(), cameraState); + const float scaledSize = + s_pivotSize * CalculateScreenToWorldMultiplier(pickedEntityWorldTransform.GetTranslation(), cameraState); debugDisplay.DepthWriteOff(); debugDisplay.DepthTestOff(); @@ -3421,8 +3289,8 @@ namespace AzToolsFramework // check what pivot orientation we are in (based on if a modifier is // held to move us from parent to world space or parent to local space) // or if we set a pivot override - const auto pivotResult = ETCS::CalculateSelectionPivotOrientation( - m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_referenceFrame); + const auto pivotResult = + ETCS::CalculateSelectionPivotOrientation(m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_referenceFrame); // if the reference frame was parent space and the selection does have a // valid parent, draw a preview axis at its position/orientation @@ -3432,8 +3300,7 @@ namespace AzToolsFramework { const AZ::Transform& worldFromLocal = m_entityDataCache->GetVisibleEntityTransform(*parentEntityIndex); - const float adjustedLineLength = - CalculateScreenToWorldMultiplier(worldFromLocal.GetTranslation(), cameraState); + const float adjustedLineLength = CalculateScreenToWorldMultiplier(worldFromLocal.GetTranslation(), cameraState); DrawPreviewAxis(debugDisplay, worldFromLocal, adjustedLineLength, cameraState); } @@ -3452,10 +3319,11 @@ namespace AzToolsFramework const AZ::Vector3 boxPosition = worldFromLocal.TransformPoint(CalculateCenterOffset(entityId, m_pivotMode)); - const AZ::Vector3 scaledSize = AZ::Vector3(s_pivotSize) * - CalculateScreenToWorldMultiplier(worldFromLocal.GetTranslation(), cameraState); + const AZ::Vector3 scaledSize = + AZ::Vector3(s_pivotSize) * CalculateScreenToWorldMultiplier(worldFromLocal.GetTranslation(), cameraState); - const AZ::Color hiddenNormal[] = { AzFramework::ViewportColors::SelectedColor, AzFramework::ViewportColors::HiddenColor }; + const AZ::Color hiddenNormal[] = { AzFramework::ViewportColors::SelectedColor, + AzFramework::ViewportColors::HiddenColor }; AZ::Color boxColor = hiddenNormal[hidden]; const AZ::Color lockedOther[] = { boxColor, AzFramework::ViewportColors::LockColor }; boxColor = lockedOther[locked]; @@ -3470,8 +3338,7 @@ namespace AzToolsFramework debugDisplay.DepthWriteOn(); debugDisplay.DepthTestOn(); - if (ShowingGrid(viewportInfo.m_viewportId) && m_mode == Mode::Translation && - !ComponentModeFramework::InComponentMode()) + if (ShowingGrid(viewportInfo.m_viewportId) && m_mode == Mode::Translation && !ComponentModeFramework::InComponentMode()) { const GridSnapParameters gridSnapParams = GridSnapSettings(viewportInfo.m_viewportId); if (gridSnapParams.m_gridSnap && m_entityIdManipulators.m_manipulators) @@ -3491,11 +3358,11 @@ namespace AzToolsFramework if (m_entityIdManipulators.m_manipulators->PerformingAction()) { - const float adjustedLineLength = 2.0f * - CalculateScreenToWorldMultiplier(m_axisPreview.m_translation, cameraState); + const float adjustedLineLength = 2.0f * CalculateScreenToWorldMultiplier(m_axisPreview.m_translation, cameraState); - DrawPreviewAxis(debugDisplay, AZ::Transform::CreateFromQuaternionAndTranslation( - m_axisPreview.m_orientation, m_axisPreview.m_translation), + DrawPreviewAxis( + debugDisplay, + AZ::Transform::CreateFromQuaternionAndTranslation(m_axisPreview.m_orientation, m_axisPreview.m_translation), adjustedLineLength, cameraState); } } @@ -3503,20 +3370,17 @@ namespace AzToolsFramework m_boxSelect.DisplayScene(viewportInfo, debugDisplay); } - static void DrawAxisGizmo( - const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) + static void DrawAxisGizmo(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) { // get the editor cameras current orientation const int viewportId = viewportInfo.m_viewportId; const AzFramework::CameraState editorCameraState = GetCameraState(viewportId); - const AZ::Matrix3x3& editorCameraOrientation = - AZ::Matrix3x3::CreateFromMatrix4x4(AzFramework::CameraTransform(editorCameraState)); + const AZ::Matrix3x3& editorCameraOrientation = AZ::Matrix3x3::CreateFromMatrix4x4(AzFramework::CameraTransform(editorCameraState)); // create a gizmo camera transform about the origin matching the orientation of the editor camera // (10 units back in the y axis to produce an orbit effect) const AZ::Transform gizmoCameraOffset = AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisY(10.0f)); - const AZ::Transform gizmoCameraTransform = - AZ::Transform::CreateFromMatrix3x3(editorCameraOrientation) * gizmoCameraOffset; + const AZ::Transform gizmoCameraTransform = AZ::Transform::CreateFromMatrix3x3(editorCameraOrientation) * gizmoCameraOffset; const AzFramework::CameraState gizmoCameraState = AzFramework::CreateDefaultCamera(gizmoCameraTransform, editorCameraState.m_viewportSize); @@ -3529,16 +3393,9 @@ namespace AzToolsFramework // map from a position in world space (relative to the the gizmo camera near the origin) to a position in // screen space - const auto calculateGizmoAxis = - [&cameraView, &cameraProjection, &screenOffset] - (const AZ::Vector3& axis) - { - auto result = AZ::Vector2( - AzFramework::WorldToScreenNDC( - axis, - cameraView, - cameraProjection) - ); + const auto calculateGizmoAxis = [&cameraView, &cameraProjection, &screenOffset](const AZ::Vector3& axis) + { + auto result = AZ::Vector2(AzFramework::WorldToScreenNDC(axis, cameraView, cameraProjection)); result.SetY(1.0f - result.GetY()); return result + screenOffset; }; @@ -3552,7 +3409,7 @@ namespace AzToolsFramework const AZ::Vector2 gizmoAxisX = gizmoEndAxisX - gizmoStart; const AZ::Vector2 gizmoAxisY = gizmoEndAxisY - gizmoStart; - const AZ::Vector2 gizmoAxisZ = gizmoEndAxisZ - gizmoStart; + const AZ::Vector2 gizmoAxisZ = gizmoEndAxisZ - gizmoStart; // draw the axes of the gizmo debugDisplay.SetLineWidth(cl_viewportGizmoAxisLineWidth); @@ -3579,8 +3436,7 @@ namespace AzToolsFramework } void EditorTransformComponentSelection::DisplayViewportSelection2d( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) + const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -3595,8 +3451,7 @@ namespace AzToolsFramework // check what the 'authoritative' selected entity ids are after an undo/redo EntityIdList selectedEntityIds; - ToolsApplicationRequests::Bus::BroadcastResult( - selectedEntityIds, &ToolsApplicationRequests::GetSelectedEntities); + ToolsApplicationRequests::Bus::BroadcastResult(selectedEntityIds, &ToolsApplicationRequests::GetSelectedEntities); RefreshSelectedEntityIds(selectedEntityIds); } @@ -3614,9 +3469,7 @@ namespace AzToolsFramework // update selected entityId set m_selectedEntityIds.clear(); m_selectedEntityIds.reserve(selectedEntityIds.size()); - AZStd::copy( - selectedEntityIds.begin(), selectedEntityIds.end(), - AZStd::inserter(m_selectedEntityIds, m_selectedEntityIds.end())); + AZStd::copy(selectedEntityIds.begin(), selectedEntityIds.end(), AZStd::inserter(m_selectedEntityIds, m_selectedEntityIds.end())); } void EditorTransformComponentSelection::OnTransformChanged( @@ -3690,8 +3543,7 @@ namespace AzToolsFramework m_selectedEntityIdsAndManipulatorsDirty = true; } - void EditorTransformComponentSelection::EnteredComponentMode( - const AZStd::vector& /*componentModeTypes*/) + void EditorTransformComponentSelection::EnteredComponentMode(const AZStd::vector& /*componentModeTypes*/) { SetViewportUiClusterVisible(m_transformModeClusterId, false); @@ -3700,8 +3552,7 @@ namespace AzToolsFramework ToolsApplicationNotificationBus::Handler::BusDisconnect(); } - void EditorTransformComponentSelection::LeftComponentMode( - const AZStd::vector& /*componentModeTypes*/) + void EditorTransformComponentSelection::LeftComponentMode(const AZStd::vector& /*componentModeTypes*/) { SetViewportUiClusterVisible(m_transformModeClusterId, true); @@ -3714,8 +3565,8 @@ namespace AzToolsFramework { if (m_entityIdManipulators.m_manipulators) { - auto manipulatorCommand = AZStd::make_unique( - CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); + auto manipulatorCommand = + AZStd::make_unique(CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName); manipulatorCommand->SetManipulatorAfter(EntityManipulatorCommand::State()); @@ -3734,32 +3585,27 @@ namespace AzToolsFramework return {}; } - void EditorTransformComponentSelection::SetEntityWorldTranslation( - const AZ::EntityId entityId, const AZ::Vector3& worldTranslation) + void EditorTransformComponentSelection::SetEntityWorldTranslation(const AZ::EntityId entityId, const AZ::Vector3& worldTranslation) { ETCS::SetEntityWorldTranslation(entityId, worldTranslation, m_transformChangedInternally); } - void EditorTransformComponentSelection::SetEntityLocalTranslation( - const AZ::EntityId entityId, const AZ::Vector3& localTranslation) + void EditorTransformComponentSelection::SetEntityLocalTranslation(const AZ::EntityId entityId, const AZ::Vector3& localTranslation) { ETCS::SetEntityLocalTranslation(entityId, localTranslation, m_transformChangedInternally); } - void EditorTransformComponentSelection::SetEntityWorldTransform( - const AZ::EntityId entityId, const AZ::Transform& worldTransform) + void EditorTransformComponentSelection::SetEntityWorldTransform(const AZ::EntityId entityId, const AZ::Transform& worldTransform) { ETCS::SetEntityWorldTransform(entityId, worldTransform, m_transformChangedInternally); } - void EditorTransformComponentSelection::SetEntityLocalScale( - const AZ::EntityId entityId, const float localScale) + void EditorTransformComponentSelection::SetEntityLocalScale(const AZ::EntityId entityId, const float localScale) { ETCS::SetEntityLocalScale(entityId, localScale, m_transformChangedInternally); } - void EditorTransformComponentSelection::SetEntityLocalRotation( - const AZ::EntityId entityId, const AZ::Vector3& localRotation) + void EditorTransformComponentSelection::SetEntityLocalRotation(const AZ::EntityId entityId, const AZ::Vector3& localRotation) { ETCS::SetEntityLocalRotation(entityId, localRotation, m_transformChangedInternally); } @@ -3788,44 +3634,37 @@ namespace AzToolsFramework void SetEntityWorldTranslation(AZ::EntityId entityId, const AZ::Vector3& worldTranslation, bool& internal) { ScopeSwitch sw(internal); - AZ::TransformBus::Event( - entityId, &AZ::TransformBus::Events::SetWorldTranslation, worldTranslation); + AZ::TransformBus::Event(entityId, &AZ::TransformBus::Events::SetWorldTranslation, worldTranslation); } void SetEntityLocalTranslation(AZ::EntityId entityId, const AZ::Vector3& localTranslation, bool& internal) { ScopeSwitch sw(internal); - AZ::TransformBus::Event( - entityId, &AZ::TransformBus::Events::SetLocalTranslation, localTranslation); + AZ::TransformBus::Event(entityId, &AZ::TransformBus::Events::SetLocalTranslation, localTranslation); } void SetEntityWorldTransform(AZ::EntityId entityId, const AZ::Transform& worldTransform, bool& internal) { ScopeSwitch sw(internal); - AZ::TransformBus::Event( - entityId, &AZ::TransformBus::Events::SetWorldTM, worldTransform); + AZ::TransformBus::Event(entityId, &AZ::TransformBus::Events::SetWorldTM, worldTransform); } void SetEntityLocalScale(AZ::EntityId entityId, float localScale, bool& internal) { ScopeSwitch sw(internal); - AZ::TransformBus::Event( - entityId, &AZ::TransformBus::Events::SetLocalUniformScale, localScale); + AZ::TransformBus::Event(entityId, &AZ::TransformBus::Events::SetLocalUniformScale, localScale); } void SetEntityLocalRotation(AZ::EntityId entityId, const AZ::Vector3& localRotation, bool& internal) { ScopeSwitch sw(internal); - AZ::TransformBus::Event( - entityId, &AZ::TransformBus::Events::SetLocalRotation, localRotation); + AZ::TransformBus::Event(entityId, &AZ::TransformBus::Events::SetLocalRotation, localRotation); } } // namespace ETCS // explicit instantiations - template ETCS::PivotOrientationResult - ETCS::CalculatePivotOrientationForEntityIds( - const EntityIdManipulatorLookups&, ReferenceFrame); - template ETCS::PivotOrientationResult - ETCS::CalculateSelectionPivotOrientation( - const EntityIdManipulatorLookups&, const OptionalFrame&, const ReferenceFrame referenceFrame); + template ETCS::PivotOrientationResult ETCS::CalculatePivotOrientationForEntityIds( + const EntityIdManipulatorLookups&, ReferenceFrame); + template ETCS::PivotOrientationResult ETCS::CalculateSelectionPivotOrientation( + const EntityIdManipulatorLookups&, const OptionalFrame&, const ReferenceFrame referenceFrame); } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.cpp index 9ca20068ed..8cd19b8d2d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.cpp @@ -1,17 +1,17 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ -#include #include "EditorTransformComponentSelectionRequestBus.h" +#include namespace AzToolsFramework { @@ -19,50 +19,68 @@ namespace AzToolsFramework { if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { - #define TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests() \ - ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) \ - ->Attribute(AZ::Script::Attributes::Category, "Editor") \ - ->Attribute(AZ::Script::Attributes::Module, "editor") +#define TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests() \ + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) \ + ->Attribute(AZ::Script::Attributes::Category, "Editor") \ + ->Attribute(AZ::Script::Attributes::Module, "editor") - behaviorContext->EnumProperty(EditorTransformComponentSelectionRequests::Mode::Rotation)>("TransformMode_Rotation") - TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests(); - behaviorContext->EnumProperty(EditorTransformComponentSelectionRequests::Mode::Translation)>("TransformMode_Translation") - TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests(); + behaviorContext->EnumProperty(EditorTransformComponentSelectionRequests::Mode::Rotation)>( + "TransformMode_Rotation") TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests(); + behaviorContext->EnumProperty(EditorTransformComponentSelectionRequests::Mode::Translation)>( + "TransformMode_Translation") TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests(); behaviorContext->EnumProperty(EditorTransformComponentSelectionRequests::Mode::Scale)>("TransformMode_Scale") TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests(); - behaviorContext->EnumProperty(EditorTransformComponentSelectionRequests::RefreshType::Translation)>("TransformRefreshType_Translation") - TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests(); - behaviorContext->EnumProperty(EditorTransformComponentSelectionRequests::RefreshType::Orientation)>("TransformRefreshType_Orientation") - TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests(); - behaviorContext->EnumProperty(EditorTransformComponentSelectionRequests::RefreshType::All)>("TransformRefreshType_All") - TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests(); + behaviorContext->EnumProperty(EditorTransformComponentSelectionRequests::RefreshType::Translation)>( + "TransformRefreshType_Translation") TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests(); + behaviorContext->EnumProperty(EditorTransformComponentSelectionRequests::RefreshType::Orientation)>( + "TransformRefreshType_Orientation") TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests(); + behaviorContext->EnumProperty(EditorTransformComponentSelectionRequests::RefreshType::All)>( + "TransformRefreshType_All") TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests(); - behaviorContext->EnumProperty(EditorTransformComponentSelectionRequests::Pivot::Object)>("TransformPivot_Object") - TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests(); - behaviorContext->EnumProperty(EditorTransformComponentSelectionRequests::Pivot::Center)>("TransformPivot_Center") - TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests(); + behaviorContext->EnumProperty(EditorTransformComponentSelectionRequests::Pivot::Object)>( + "TransformPivot_Object") TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests(); + behaviorContext->EnumProperty(EditorTransformComponentSelectionRequests::Pivot::Center)>( + "TransformPivot_Center") TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests(); - behaviorContext->EBus("EditorTransformComponentSelectionRequestBus") - TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests() + behaviorContext + ->EBus("EditorTransformComponentSelectionRequestBus") + TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests() ->Event("SetTransformMode", &EditorTransformComponentSelectionRequestBus::Events::SetTransformMode) ->Event("GetTransformMode", &EditorTransformComponentSelectionRequestBus::Events::GetTransformMode) // Reflecting GetManipulatorTransform will require hash to be implemented, a pending task. //->Event("GetManipulatorTransform", &EditorTransformComponentSelectionRequestBus::Events::GetManipulatorTransform) ->Event("RefreshManipulators", &EditorTransformComponentSelectionRequestBus::Events::RefreshManipulators) - ->Event("OverrideManipulatorOrientation", &EditorTransformComponentSelectionRequestBus::Events::OverrideManipulatorOrientation) - ->Event("OverrideManipulatorTranslation", &EditorTransformComponentSelectionRequestBus::Events::OverrideManipulatorTranslation) - ->Event("CopyTranslationToSelectedEntitiesIndividual", &EditorTransformComponentSelectionRequestBus::Events::CopyTranslationToSelectedEntitiesIndividual) - ->Event("CopyTranslationToSelectedEntitiesGroup", &EditorTransformComponentSelectionRequestBus::Events::CopyTranslationToSelectedEntitiesGroup) - ->Event("ResetTranslationForSelectedEntitiesLocal", &EditorTransformComponentSelectionRequestBus::Events::ResetTranslationForSelectedEntitiesLocal) - ->Event("CopyOrientationToSelectedEntitiesIndividual", &EditorTransformComponentSelectionRequestBus::Events::CopyOrientationToSelectedEntitiesIndividual) - ->Event("CopyOrientationToSelectedEntitiesGroup", &EditorTransformComponentSelectionRequestBus::Events::CopyOrientationToSelectedEntitiesGroup) - ->Event("ResetOrientationForSelectedEntitiesLocal", &EditorTransformComponentSelectionRequestBus::Events::ResetOrientationForSelectedEntitiesLocal) - ->Event("CopyScaleToSelectedEntitiesIndividualLocal", &EditorTransformComponentSelectionRequestBus::Events::CopyScaleToSelectedEntitiesIndividualLocal) - ->Event("CopyScaleToSelectedEntitiesIndividualWorld", &EditorTransformComponentSelectionRequestBus::Events::CopyScaleToSelectedEntitiesIndividualWorld) - ; + ->Event( + "OverrideManipulatorOrientation", &EditorTransformComponentSelectionRequestBus::Events::OverrideManipulatorOrientation) + ->Event( + "OverrideManipulatorTranslation", &EditorTransformComponentSelectionRequestBus::Events::OverrideManipulatorTranslation) + ->Event( + "CopyTranslationToSelectedEntitiesIndividual", + &EditorTransformComponentSelectionRequestBus::Events::CopyTranslationToSelectedEntitiesIndividual) + ->Event( + "CopyTranslationToSelectedEntitiesGroup", + &EditorTransformComponentSelectionRequestBus::Events::CopyTranslationToSelectedEntitiesGroup) + ->Event( + "ResetTranslationForSelectedEntitiesLocal", + &EditorTransformComponentSelectionRequestBus::Events::ResetTranslationForSelectedEntitiesLocal) + ->Event( + "CopyOrientationToSelectedEntitiesIndividual", + &EditorTransformComponentSelectionRequestBus::Events::CopyOrientationToSelectedEntitiesIndividual) + ->Event( + "CopyOrientationToSelectedEntitiesGroup", + &EditorTransformComponentSelectionRequestBus::Events::CopyOrientationToSelectedEntitiesGroup) + ->Event( + "ResetOrientationForSelectedEntitiesLocal", + &EditorTransformComponentSelectionRequestBus::Events::ResetOrientationForSelectedEntitiesLocal) + ->Event( + "CopyScaleToSelectedEntitiesIndividualLocal", + &EditorTransformComponentSelectionRequestBus::Events::CopyScaleToSelectedEntitiesIndividualLocal) + ->Event( + "CopyScaleToSelectedEntitiesIndividualWorld", + &EditorTransformComponentSelectionRequestBus::Events::CopyScaleToSelectedEntitiesIndividualWorld); - #undef TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests +#undef TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests } } } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.h index 9cd78f8c50..966f9333fc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -16,12 +16,10 @@ #include #include - namespace AzToolsFramework { - /// Provide interface for EditorTransformComponentSelection requests. - class EditorTransformComponentSelectionRequests - : public AZ::EBusTraits + //! Provide interface for EditorTransformComponentSelection requests. + class EditorTransformComponentSelectionRequests : public AZ::EBusTraits { public: using BusIdType = AzFramework::EntityContextId; @@ -30,7 +28,7 @@ namespace AzToolsFramework static void Reflect(AZ::ReflectContext* context); - /// What type of transform editing are we in. + //! What type of transform editing are we in. enum class Mode { // note: ordering of these is important - do not change. @@ -40,7 +38,7 @@ namespace AzToolsFramework Scale }; - /// Specify the type of refresh (what type of transform modification caused the refresh). + //! Specify the type of refresh (what type of transform modification caused the refresh). enum class RefreshType { Translation, @@ -48,69 +46,69 @@ namespace AzToolsFramework All }; - /// How is the pivot aligned (object/authored position or center). + //! How is the pivot aligned (object/authored position or center). enum class Pivot { Object, Center }; - /// Set what kind of transform the type that implements this bus should use. + //! Set what kind of transform the type that implements this bus should use. virtual void SetTransformMode(Mode mode) = 0; - /// Return what transform mode the type that implements this bus is using. + //! Return what transform mode the type that implements this bus is using. virtual Mode GetTransformMode() = 0; - /// Return the current Entity Manipulator transform. - /// An AZStd::optional is returned as if we do not have a selection - /// there will be no Manipulator present. In this case we return an empty optional. + //! Return the current Entity Manipulator transform. + //! An AZStd::optional is returned as if we do not have a selection + //! there will be no Manipulator present. In this case we return an empty optional. virtual AZStd::optional GetManipulatorTransform() = 0; - /// Refresh the Manipulator based on the current entity selection. - /// This may be useful if the Entity transform has been set outside - /// of the EditorTransformComponentSelection and we want to make sure the - /// Manipulator stays up to date (in sync) with the current Entity transform. + //! Refresh the Manipulator based on the current entity selection. + //! This may be useful if the Entity transform has been set outside + //! of the EditorTransformComponentSelection and we want to make sure the + //! Manipulator stays up to date (in sync) with the current Entity transform. virtual void RefreshManipulators(RefreshType refreshType) = 0; - /// Set an orientation override for the Manipulator. - /// Useful if we've picked another Entity transform to use as our reference point. + //! Set an orientation override for the Manipulator. + //! Useful if we've picked another Entity transform to use as our reference point. virtual void OverrideManipulatorOrientation(const AZ::Quaternion& orientation) = 0; - /// Set a translation override for the Manipulator. - /// Useful if we've picked another Entity transform to use as our reference point. + //! Set a translation override for the Manipulator. + //! Useful if we've picked another Entity transform to use as our reference point. virtual void OverrideManipulatorTranslation(const AZ::Vector3& translation) = 0; - /// Copy translation to each individual entity so they all appear in the exact same position. + //! Copy translation to each individual entity so they all appear in the exact same position. virtual void CopyTranslationToSelectedEntitiesIndividual(const AZ::Vector3& translation) = 0; - /// Copy translation to manipulator position with each entity keeping the same relative position as before. + //! Copy translation to manipulator position with each entity keeping the same relative position as before. virtual void CopyTranslationToSelectedEntitiesGroup(const AZ::Vector3& translation) = 0; - /// Reset the translation of an entity to the same position as its parent. - /// Note: This is a noop if the entity does not have a parent. + //! Reset the translation of an entity to the same position as its parent. + //! Note: This is a noop if the entity does not have a parent. virtual void ResetTranslationForSelectedEntitiesLocal() = 0; - /// Copy orientation to each individual entity so they all appear in the exact same orientation. + //! Copy orientation to each individual entity so they all appear in the exact same orientation. virtual void CopyOrientationToSelectedEntitiesIndividual(const AZ::Quaternion& orientation) = 0; - /// Copy orientation to manipulator with each entity keeping the same relative orientation as before. + //! Copy orientation to manipulator with each entity keeping the same relative orientation as before. virtual void CopyOrientationToSelectedEntitiesGroup(const AZ::Quaternion& orientation) = 0; - /// Reset the orientation of an entity to the same orientation as its parent. - /// Note: This will be the aligned to the world axes (identity) if the entity does not have a parent. + //! Reset the orientation of an entity to the same orientation as its parent. + //! Note: This will be the aligned to the world axes (identity) if the entity does not have a parent. virtual void ResetOrientationForSelectedEntitiesLocal() = 0; - /// Copy scale to each individual entity in local space without moving position. + //! Copy scale to each individual entity in local space without moving position. virtual void CopyScaleToSelectedEntitiesIndividualLocal(float scale) = 0; - /// Copy scale to to each individual entity in world (absolute) space. + //! Copy scale to to each individual entity in world (absolute) space. virtual void CopyScaleToSelectedEntitiesIndividualWorld(float scale) = 0; protected: ~EditorTransformComponentSelectionRequests() = default; }; - /// Type to inherit to implement EditorTransformComponentSelectionRequests. + //! Type to inherit to implement EditorTransformComponentSelectionRequests. using EditorTransformComponentSelectionRequestBus = AZ::EBus; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.cpp index 253c27fe02..0e066684d2 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.cpp @@ -1,33 +1,31 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "EditorVisibleEntityDataCache.h" #include +#include #include #include -#include namespace AzToolsFramework { - /// Cached Entity data required by the selection. + //! Cached Entity data required by the selection. struct EntityData final { using ComponentEntityAccentType = Components::EditorSelectionAccentSystemComponent::ComponentEntityAccentType; EntityData() = default; - EntityData( - AZ::EntityId entityId, const AZ::Transform& worldFromLocal, - bool locked, bool visible, bool selected, bool iconHidden); + EntityData(AZ::EntityId entityId, const AZ::Transform& worldFromLocal, bool locked, bool visible, bool selected, bool iconHidden); AZ::Transform m_worldFromLocal; AZ::EntityId m_entityId; @@ -38,7 +36,7 @@ namespace AzToolsFramework bool m_iconHidden = false; }; - using EntityDatas = AZStd::vector; ///< Alias for vector of EntityDatas. + using EntityDatas = AZStd::vector; //!< Alias for vector of EntityDatas. // Predicate to sort EntityIds with EntityDatas interchangeably. struct EntityDataComparer @@ -52,18 +50,27 @@ namespace AzToolsFramework class EditorVisibleEntityDataCache::EditorVisibleEntityDataCacheImpl { public: - EntityIdList m_visibleEntityIds; ///< The EntityIds that are visible this frame. - EntityIdList m_prevVisibleEntityIds; ///< The EntityIds that were visible the previous frame (unsorted). - EntityDatas m_visibleEntityDatas; ///< Cached EntityData required by EditorTransformComponentSelection. + EntityIdList m_visibleEntityIds; //!< The EntityIds that are visible this frame. + EntityIdList m_prevVisibleEntityIds; //!< The EntityIds that were visible the previous frame (unsorted). + EntityDatas m_visibleEntityDatas; //!< Cached EntityData required by EditorTransformComponentSelection. }; // constructor for EntityData to support emplace_back in vector EntityData::EntityData( - const AZ::EntityId entityId, const AZ::Transform& worldFromLocal, - const bool locked, const bool visible, const bool selected, const bool iconHidden) - : m_worldFromLocal(worldFromLocal), m_entityId(entityId) - , m_locked(locked), m_visible(visible), m_selected(selected) - , m_iconHidden(iconHidden) {} + const AZ::EntityId entityId, + const AZ::Transform& worldFromLocal, + const bool locked, + const bool visible, + const bool selected, + const bool iconHidden) + : m_worldFromLocal(worldFromLocal) + , m_entityId(entityId) + , m_locked(locked) + , m_visible(visible) + , m_selected(selected) + , m_iconHidden(iconHidden) + { + } bool EntityDataComparer::operator()(const AZ::EntityId lhs, const EntityData& rhs) const { @@ -98,20 +105,17 @@ namespace AzToolsFramework static EntityData EntityDataFromEntityId(const AZ::EntityId entityId) { bool visible = false; - EditorEntityInfoRequestBus::EventResult( - visible, entityId, &EditorEntityInfoRequestBus::Events::IsVisible); + EditorEntityInfoRequestBus::EventResult(visible, entityId, &EditorEntityInfoRequestBus::Events::IsVisible); bool locked = false; - EditorEntityInfoRequestBus::EventResult( - locked, entityId, &EditorEntityInfoRequestBus::Events::IsLocked); + EditorEntityInfoRequestBus::EventResult(locked, entityId, &EditorEntityInfoRequestBus::Events::IsLocked); bool iconHidden = false; EditorEntityIconComponentRequestBus::EventResult( iconHidden, entityId, &EditorEntityIconComponentRequests::IsEntityIconHiddenInViewport); AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity(); - AZ::TransformBus::EventResult( - worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM); + AZ::TransformBus::EventResult(worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM); return { entityId, worldFromLocal, locked, visible, IsSelected(entityId), iconHidden }; } @@ -155,16 +159,14 @@ namespace AzToolsFramework AZStd::sort(m_impl->m_visibleEntityDatas.begin(), m_impl->m_visibleEntityDatas.end()); } - void EditorVisibleEntityDataCache::CalculateVisibleEntityDatas( - const AzFramework::ViewportInfo& viewportInfo) + void EditorVisibleEntityDataCache::CalculateVisibleEntityDatas(const AzFramework::ViewportInfo& viewportInfo) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); // request list of visible entities from authoritative system EntityIdList nextVisibleEntityIds; ViewportInteraction::MainEditorViewportInteractionRequestBus::Event( - viewportInfo.m_viewportId, - &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::FindVisibleEntities, + viewportInfo.m_viewportId, &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::FindVisibleEntities, nextVisibleEntityIds); // only bother resorting if we know the lists have changed @@ -181,31 +183,26 @@ namespace AzToolsFramework // find entities that are visible this frame but weren't last frame AZStd::vector added; std::set_difference( - m_impl->m_visibleEntityIds.begin(), m_impl->m_visibleEntityIds.end(), - m_impl->m_visibleEntityDatas.begin(), m_impl->m_visibleEntityDatas.end(), - std::back_inserter(added), EntityDataComparer()); + m_impl->m_visibleEntityIds.begin(), m_impl->m_visibleEntityIds.end(), m_impl->m_visibleEntityDatas.begin(), + m_impl->m_visibleEntityDatas.end(), std::back_inserter(added), EntityDataComparer()); // find entities that are not visible this frame but were last frame AZStd::vector removed; std::set_difference( - m_impl->m_visibleEntityDatas.begin(), m_impl->m_visibleEntityDatas.end(), - m_impl->m_visibleEntityIds.begin(), m_impl->m_visibleEntityIds.end(), - std::back_inserter(removed), EntityDataComparer()); + m_impl->m_visibleEntityDatas.begin(), m_impl->m_visibleEntityDatas.end(), m_impl->m_visibleEntityIds.begin(), + m_impl->m_visibleEntityIds.end(), std::back_inserter(removed), EntityDataComparer()); // search for entityData in removed list, return true if it is found const auto removePredicate = [&removed](const EntityData& entityData) { - const auto removeIt = std::equal_range( - removed.begin(), removed.end(), entityData); + const auto removeIt = std::equal_range(removed.begin(), removed.end(), entityData); return removeIt.first != removeIt.second; }; // erase-remove idiom - bubble entities to be removed to the end, then erase them in one go m_impl->m_visibleEntityDatas.erase( - AZStd::remove_if( - m_impl->m_visibleEntityDatas.begin(), - m_impl->m_visibleEntityDatas.end(), removePredicate), + AZStd::remove_if(m_impl->m_visibleEntityDatas.begin(), m_impl->m_visibleEntityDatas.end(), removePredicate), m_impl->m_visibleEntityDatas.end()); // for newly added entities, request their initial state when first cached @@ -240,8 +237,7 @@ namespace AzToolsFramework return m_impl->m_visibleEntityDatas[index].m_entityId; } - EditorVisibleEntityDataCache::ComponentEntityAccentType EditorVisibleEntityDataCache::GetVisibleEntityAccent( - const size_t index) const + EditorVisibleEntityDataCache::ComponentEntityAccentType EditorVisibleEntityDataCache::GetVisibleEntityAccent(const size_t index) const { return m_impl->m_visibleEntityDatas[index].m_accent; } @@ -273,8 +269,8 @@ namespace AzToolsFramework AZStd::optional EditorVisibleEntityDataCache::GetVisibleEntityIndexFromId(const AZ::EntityId entityId) const { - const auto entityIdIt = std::equal_range( - m_impl->m_visibleEntityDatas.begin(), m_impl->m_visibleEntityDatas.end(), entityId, EntityDataComparer()); + const auto entityIdIt = + std::equal_range(m_impl->m_visibleEntityDatas.begin(), m_impl->m_visibleEntityDatas.end(), entityId, EntityDataComparer()); if (entityIdIt.first != entityIdIt.second) { @@ -318,8 +314,7 @@ namespace AzToolsFramework } } - void EditorVisibleEntityDataCache::OnTransformChanged( - const AZ::Transform& /*local*/, const AZ::Transform& world) + void EditorVisibleEntityDataCache::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -367,8 +362,7 @@ namespace AzToolsFramework } } - void EditorVisibleEntityDataCache::OnEntityIconChanged( - const AZ::Data::AssetId& /*entityIconAssetId*/) + void EditorVisibleEntityDataCache::OnEntityIconChanged(const AZ::Data::AssetId& /*entityIconAssetId*/) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.h index 72c1595e7b..0d74825bf8 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -22,8 +22,8 @@ namespace AzToolsFramework { - /// A cache of packed EntityData that can be iterated over efficiently without - /// the need to make individual EBus calls + //! A cache of packed EntityData that can be iterated over efficiently without + //! the need to make individual EBus calls class EditorVisibleEntityDataCache : private EditorEntityVisibilityNotificationBus::Router , private EditorEntityLockComponentNotificationBus::Router @@ -45,7 +45,7 @@ namespace AzToolsFramework void CalculateVisibleEntityDatas(const AzFramework::ViewportInfo& viewportInfo); - /// EditorVisibleEntityDataCache interface + //! EditorVisibleEntityDataCache interface size_t VisibleEntityDataCount() const; AZ::Vector3 GetVisibleEntityPosition(size_t index) const; const AZ::Transform& GetVisibleEntityTransform(size_t index) const; @@ -72,8 +72,7 @@ namespace AzToolsFramework void OnEntityLockChanged(bool locked) override; // TransformNotificationBus - void OnTransformChanged( - const AZ::Transform& local, const AZ::Transform& world) override; + void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; // EditorComponentSelectionNotificationsBus void OnAccentTypeChanged(EntityAccentType accent) override; @@ -86,6 +85,6 @@ namespace AzToolsFramework void OnEntityIconChanged(const AZ::Data::AssetId& entityIconAssetId) override; class EditorVisibleEntityDataCacheImpl; - AZStd::unique_ptr m_impl; ///< Internal representation of entity data cache. + AZStd::unique_ptr m_impl; //!< Internal representation of entity data cache. }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/Tests/ComponentModeTests.cpp b/Code/Framework/AzToolsFramework/Tests/ComponentModeTests.cpp index a4ee80fa5f..45699ddb78 100644 --- a/Code/Framework/AzToolsFramework/Tests/ComponentModeTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/ComponentModeTests.cpp @@ -1,30 +1,31 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include "ComponentModeTestDoubles.h" #include "ComponentModeTestFixture.h" #include +#include #include #include #include -#include #include +#include #include #include #include #include -#include #include +#include #include #include #include @@ -32,7 +33,6 @@ #include #include #include -#include #include namespace UnitTest @@ -47,19 +47,16 @@ namespace UnitTest /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Given QWidget rootWidget; - ActionOverrideRequestBus::Event( - GetEntityContextId(), &ActionOverrideRequests::SetupActionOverrideHandler, &rootWidget); + ActionOverrideRequestBus::Event(GetEntityContextId(), &ActionOverrideRequests::SetupActionOverrideHandler, &rootWidget); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When ComponentModeSystemRequestBus::Broadcast( - &ComponentModeSystemRequests::BeginComponentMode, - AZStd::vector{}); + &ComponentModeSystemRequests::BeginComponentMode, AZStd::vector{}); bool inComponentMode = false; - ComponentModeSystemRequestBus::BroadcastResult( - inComponentMode, &ComponentModeSystemRequests::InComponentMode); + ComponentModeSystemRequestBus::BroadcastResult(inComponentMode, &ComponentModeSystemRequests::InComponentMode); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -69,11 +66,9 @@ namespace UnitTest /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When - ComponentModeSystemRequestBus::Broadcast( - &ComponentModeSystemRequests::EndComponentMode); + ComponentModeSystemRequestBus::Broadcast(&ComponentModeSystemRequests::EndComponentMode); - ComponentModeSystemRequestBus::BroadcastResult( - inComponentMode, &ComponentModeSystemRequests::InComponentMode); + ComponentModeSystemRequestBus::BroadcastResult(inComponentMode, &ComponentModeSystemRequests::InComponentMode); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -81,8 +76,7 @@ namespace UnitTest EXPECT_FALSE(inComponentMode); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// - ActionOverrideRequestBus::Event( - GetEntityContextId(), &ActionOverrideRequests::TeardownActionOverrideHandler); + ActionOverrideRequestBus::Event(GetEntityContextId(), &ActionOverrideRequests::TeardownActionOverrideHandler); } TEST_F(ComponentModeTestFixture, TwoComponentsOnSingleEntityWithSameComponentModeBothBegin) @@ -104,8 +98,7 @@ namespace UnitTest // mimic selecting the entity in the viewport (after selection the ComponentModeDelegate // connects to the ComponentModeDelegateRequestBus on the entity/component pair address) const AzToolsFramework::EntityIdList entityIds = { entityId }; - ToolsApplicationRequestBus::Broadcast( - &ToolsApplicationRequests::SetSelectedEntities, entityIds); + ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, entityIds); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -113,8 +106,7 @@ namespace UnitTest // move all selected components into ComponentMode // (mimic pressing the 'Edit' button to begin Component Mode) ComponentModeSystemRequestBus::Broadcast( - &ComponentModeSystemRequests::AddSelectedComponentModesOfType, - AZ::AzTypeInfo::Uuid()); + &ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo::Uuid()); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -152,8 +144,7 @@ namespace UnitTest // mimic selecting the entity in the viewport (after selection the ComponentModeDelegate // connects to the ComponentModeDelegateRequestBus on the entity/component pair address) const AzToolsFramework::EntityIdList entityIds = { entityId }; - ToolsApplicationRequestBus::Broadcast( - &ToolsApplicationRequests::SetSelectedEntities, entityIds); + ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, entityIds); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -161,8 +152,7 @@ namespace UnitTest // move all selected components into ComponentMode // (mimic pressing the 'Edit' button to begin Component Mode) ComponentModeSystemRequestBus::Broadcast( - &ComponentModeSystemRequests::AddSelectedComponentModesOfType, - AZ::AzTypeInfo::Uuid()); + &ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo::Uuid()); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -202,8 +192,7 @@ namespace UnitTest // mimic selecting the entity in the viewport (after selection the ComponentModeDelegate // connects to the ComponentModeDelegateRequestBus on the entity/component pair address) const AzToolsFramework::EntityIdList entityIds = { entityId }; - ToolsApplicationRequestBus::Broadcast( - &ToolsApplicationRequests::SetSelectedEntities, entityIds); + ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, entityIds); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -211,16 +200,13 @@ namespace UnitTest // move all selected components into ComponentMode // (mimic pressing the 'Edit' button to begin Component Mode) ComponentModeSystemRequestBus::Broadcast( - &ComponentModeSystemRequests::AddSelectedComponentModesOfType, - AZ::AzTypeInfo::Uuid()); + &ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo::Uuid()); bool nextModeCycled = true; - ComponentModeSystemRequestBus::BroadcastResult( - nextModeCycled, &ComponentModeSystemRequests::SelectNextActiveComponentMode); + ComponentModeSystemRequestBus::BroadcastResult(nextModeCycled, &ComponentModeSystemRequests::SelectNextActiveComponentMode); bool previousModeCycled = true; - ComponentModeSystemRequestBus::BroadcastResult( - previousModeCycled, &ComponentModeSystemRequests::SelectPreviousActiveComponentMode); + ComponentModeSystemRequestBus::BroadcastResult(previousModeCycled, &ComponentModeSystemRequests::SelectPreviousActiveComponentMode); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -250,8 +236,7 @@ namespace UnitTest // mimic selecting the entity in the viewport (after selection the ComponentModeDelegate // connects to the ComponentModeDelegateRequestBus on the entity/component pair address) const AzToolsFramework::EntityIdList entityIds = { entityId }; - ToolsApplicationRequestBus::Broadcast( - &ToolsApplicationRequests::SetSelectedEntities, entityIds); + ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, entityIds); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -259,15 +244,13 @@ namespace UnitTest // move all selected components into ComponentMode // (mimic pressing the 'Edit' button to begin Component Mode) ComponentModeSystemRequestBus::Broadcast( - &ComponentModeSystemRequests::AddSelectedComponentModesOfType, - AZ::AzTypeInfo::Uuid()); + &ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo::Uuid()); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then bool multipleComponentModeTypes = true; - ComponentModeSystemRequestBus::BroadcastResult( - multipleComponentModeTypes, &ComponentModeSystemRequests::HasMultipleComponentTypes); + ComponentModeSystemRequestBus::BroadcastResult(multipleComponentModeTypes, &ComponentModeSystemRequests::HasMultipleComponentTypes); EXPECT_FALSE(multipleComponentModeTypes); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -294,8 +277,7 @@ namespace UnitTest // mimic selecting the entity in the viewport (after selection the ComponentModeDelegate // connects to the ComponentModeDelegateRequestBus on the entity/component pair address) const AzToolsFramework::EntityIdList entityIds = { entityId }; - ToolsApplicationRequestBus::Broadcast( - &ToolsApplicationRequests::SetSelectedEntities, entityIds); + ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, entityIds); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -303,15 +285,13 @@ namespace UnitTest // move all selected components into ComponentMode // (mimic pressing the 'Edit' button to begin Component Mode) ComponentModeSystemRequestBus::Broadcast( - &ComponentModeSystemRequests::AddSelectedComponentModesOfType, - AZ::AzTypeInfo::Uuid()); + &ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo::Uuid()); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then bool multipleComponentModeTypes = true; - ComponentModeSystemRequestBus::BroadcastResult( - multipleComponentModeTypes, &ComponentModeSystemRequests::HasMultipleComponentTypes); + ComponentModeSystemRequestBus::BroadcastResult(multipleComponentModeTypes, &ComponentModeSystemRequests::HasMultipleComponentTypes); EXPECT_FALSE(multipleComponentModeTypes); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -341,8 +321,7 @@ namespace UnitTest // mimic selecting the entity in the viewport (after selection the ComponentModeDelegate // connects to the ComponentModeDelegateRequestBus on the entity/component pair address) const AzToolsFramework::EntityIdList entityIds = { entityId }; - ToolsApplicationRequestBus::Broadcast( - &ToolsApplicationRequests::SetSelectedEntities, entityIds); + ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, entityIds); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -350,15 +329,13 @@ namespace UnitTest // move all selected components into ComponentMode // (mimic pressing the 'Edit' button to begin Component Mode) ComponentModeSystemRequestBus::Broadcast( - &ComponentModeSystemRequests::AddSelectedComponentModesOfType, - AZ::AzTypeInfo::Uuid()); + &ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo::Uuid()); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then bool multipleComponentModeTypes = false; - ComponentModeSystemRequestBus::BroadcastResult( - multipleComponentModeTypes, &ComponentModeSystemRequests::HasMultipleComponentTypes); + ComponentModeSystemRequestBus::BroadcastResult(multipleComponentModeTypes, &ComponentModeSystemRequests::HasMultipleComponentTypes); bool secondComponentModeInstantiated = false; ComponentModeSystemRequestBus::BroadcastResult( @@ -366,8 +343,7 @@ namespace UnitTest AZ::EntityComponentIdPair(entityId, placeholder2->GetId())); AZ::Uuid activeComponentType = AZ::Uuid::CreateNull(); - ComponentModeSystemRequestBus::BroadcastResult( - activeComponentType, &ComponentModeSystemRequests::ActiveComponentMode); + ComponentModeSystemRequestBus::BroadcastResult(activeComponentType, &ComponentModeSystemRequests::ActiveComponentMode); EXPECT_TRUE(multipleComponentModeTypes); EXPECT_TRUE(secondComponentModeInstantiated); @@ -412,13 +388,11 @@ namespace UnitTest // Component Mode is will sent the notification to the correct address. ComponentModeActionSignalRequestBus::Event( AZ::EntityComponentIdPair(entityId, placeholder1->GetId()), - &ComponentModeActionSignalRequests::SetComponentModeActionNotificationBusToNotify, - checkerBusId); + &ComponentModeActionSignalRequests::SetComponentModeActionNotificationBusToNotify, checkerBusId); ComponentModeActionSignalRequestBus::Event( AZ::EntityComponentIdPair(entityId, placeholder2->GetId()), - &ComponentModeActionSignalRequests::SetComponentModeActionNotificationBusToNotify, - checkerBusId); + &ComponentModeActionSignalRequests::SetComponentModeActionNotificationBusToNotify, checkerBusId); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -470,8 +444,7 @@ namespace UnitTest using MouseInteractionResult = AzToolsFramework::ViewportInteraction::MouseInteractionResult; MouseInteractionResult handled = MouseInteractionResult::None; EditorInteractionSystemViewportSelectionRequestBus::BroadcastResult( - handled, &EditorInteractionSystemViewportSelectionRequestBus::Events::InternalHandleAllMouseInteractions, - interactionEvent); + handled, &EditorInteractionSystemViewportSelectionRequestBus::Events::InternalHandleAllMouseInteractions, interactionEvent); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -482,8 +455,7 @@ namespace UnitTest } // Test version of EntityPropertyEditor to detect/ensure certain functions were called - class TestEntityPropertyEditor - : public AzToolsFramework::EntityPropertyEditor + class TestEntityPropertyEditor : public AzToolsFramework::EntityPropertyEditor { public: void InvalidatePropertyDisplay(PropertyModificationRefreshLevel level) override; @@ -496,8 +468,7 @@ namespace UnitTest } // Simple fixture to encapsulate a TestEntityPropertyEditor - class ComponentModePinnedSelectionFixture - : public ToolsApplicationFixture + class ComponentModePinnedSelectionFixture : public ToolsApplicationFixture { public: void SetUpEditorFixtureImpl() override @@ -533,7 +504,7 @@ namespace UnitTest /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When // select entity - const auto selectedEntities = AzToolsFramework::EntityIdList { entityId }; + const auto selectedEntities = AzToolsFramework::EntityIdList{ entityId }; SelectEntities(selectedEntities); // pin entity @@ -549,8 +520,7 @@ namespace UnitTest EXPECT_TRUE(m_testEntityPropertyEditor->IsLockedToSpecificEntities()); EXPECT_TRUE(m_testEntityPropertyEditor->m_invalidatePropertyDisplayCalled); - bool couldBeginComponentMode = - AzToolsFramework::ComponentModeFramework::CouldBeginComponentModeWithEntity(entityId); + bool couldBeginComponentMode = AzToolsFramework::ComponentModeFramework::CouldBeginComponentModeWithEntity(entityId); EXPECT_FALSE(couldBeginComponentMode); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -566,29 +536,26 @@ namespace UnitTest entity->Deactivate(); AzToolsFramework::EntityCompositionRequestBus::Broadcast( - &AzToolsFramework::EntityCompositionRequestBus::Events::AddComponentsToEntities, - AzToolsFramework::EntityIdList{entityId}, + &AzToolsFramework::EntityCompositionRequestBus::Events::AddComponentsToEntities, AzToolsFramework::EntityIdList{ entityId }, AZ::ComponentTypeList{ AZ::AzTypeInfo::Uuid() }); AzToolsFramework::EntityCompositionRequestBus::Broadcast( - &AzToolsFramework::EntityCompositionRequestBus::Events::AddComponentsToEntities, - AzToolsFramework::EntityIdList{entityId}, - AZ::ComponentTypeList{AZ::AzTypeInfo::Uuid()}); + &AzToolsFramework::EntityCompositionRequestBus::Events::AddComponentsToEntities, AzToolsFramework::EntityIdList{ entityId }, + AZ::ComponentTypeList{ AZ::AzTypeInfo::Uuid() }); entity->Activate(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When - SelectEntities(AzToolsFramework::EntityIdList{entityId}); + SelectEntities(AzToolsFramework::EntityIdList{ entityId }); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Then AZ::Entity::ComponentArrayType pendingComponents; AzToolsFramework::EditorPendingCompositionRequestBus::Event( - entityId, &AzToolsFramework::EditorPendingCompositionRequestBus::Events::GetPendingComponents, - pendingComponents); + entityId, &AzToolsFramework::EditorPendingCompositionRequestBus::Events::GetPendingComponents, pendingComponents); // ensure we do have pending components EXPECT_EQ(pendingComponents.size(), 1); From 1a6b6d5bc0e90ac9c2691124f2240e8cfef3123a Mon Sep 17 00:00:00 2001 From: jackalbe <23512001+jackalbe@users.noreply.github.com> Date: Mon, 7 Jun 2021 09:04:37 -0500 Subject: [PATCH 15/15] {LYN-4230} Fixed loading *.pak files in Release builds (#1127) * {LYN-4230} Fixed loading *.pak files in Release builds * Helios - Release mode should load all *.pak files * Tests: made a separate installation folder with a reduced "engine.pak" and a full "game.pak" which loads in release * added unit test to regress the bug fix --- .../AzFramework/Archive/Archive.cpp | 12 +++---- Code/Framework/Tests/ArchiveTests.cpp | 33 +++++++++++++++++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Archive/Archive.cpp b/Code/Framework/AzFramework/AzFramework/Archive/Archive.cpp index 4a80db2b24..04573eb2e5 100644 --- a/Code/Framework/AzFramework/AzFramework/Archive/Archive.cpp +++ b/Code/Framework/AzFramework/AzFramework/Archive/Archive.cpp @@ -1681,13 +1681,11 @@ namespace AZ::IO AZStd::vector files; do { - if (AZStd::wildcard_match(pWildcardIn, fileIterator.m_filename)) - { - AZStd::string foundFilename{ fileIterator.m_filename }; - AZStd::to_lower(foundFilename.begin(), foundFilename.end()); - files.emplace_back(AZStd::move(foundFilename)); - } - } while (fileIterator = FindNext(fileIterator)); + AZStd::string foundFilename{ fileIterator.m_filename }; + AZStd::to_lower(foundFilename.begin(), foundFilename.end()); + files.emplace_back(AZStd::move(foundFilename)); + } + while (fileIterator = FindNext(fileIterator)); // Open files in alphabet order. AZStd::sort(files.begin(), files.end()); diff --git a/Code/Framework/Tests/ArchiveTests.cpp b/Code/Framework/Tests/ArchiveTests.cpp index 6dc081ee72..ddc7060083 100644 --- a/Code/Framework/Tests/ArchiveTests.cpp +++ b/Code/Framework/Tests/ArchiveTests.cpp @@ -281,6 +281,39 @@ namespace UnitTest TestFGetCachedFileData(fileInArchiveFile, dataString.size(), dataString.data()); } + TEST_F(ArchiveTestFixture, TestArchiveOpenPacks_FindsMultiplePaks_Works) + { + AZ::IO::IArchive* archive = AZ::Interface::Get(); + ASSERT_NE(nullptr, archive); + + AZ::IO::FileIOBase* fileIo = AZ::IO::FileIOBase::GetInstance(); + ASSERT_NE(nullptr, fileIo); + + auto resetArchiveFile = [archive, fileIo](const AZStd::string& filePath) + { + archive->ClosePack(filePath.c_str()); + fileIo->Remove(filePath.c_str()); + + auto pArchive = archive->OpenArchive(filePath.c_str(), nullptr, AZ::IO::INestedArchive::FLAGS_CREATE_NEW); + EXPECT_NE(nullptr, pArchive); + pArchive.reset(); + archive->ClosePack(filePath.c_str()); + }; + + AZStd::string testArchivePath_pakOne = "@usercache@/one.pak"; + AZStd::string testArchivePath_pakTwo = "@usercache@/two.pak"; + + // reset test files in case they already exist + resetArchiveFile(testArchivePath_pakOne); + resetArchiveFile(testArchivePath_pakTwo); + + // open and fetch the opened pak file using a *.pak + AZStd::vector fullPaths; + archive->OpenPacks("@usercache@/*.pak", AZ::IO::IArchive::EPathResolutionRules::FLAGS_PATH_REAL, &fullPaths); + EXPECT_TRUE(AZStd::any_of(fullPaths.cbegin(), fullPaths.cend(), [](auto& path) { return path.ends_with("one.pak"); })); + EXPECT_TRUE(AZStd::any_of(fullPaths.cbegin(), fullPaths.cend(), [](auto& path) { return path.ends_with("two.pak"); })); + } + TEST_F(ArchiveTestFixture, TestArchiveFGetCachedFileData_LooseFile) { // ------setup loose file FGetCachedFileData tests -------------------------