Integrating latest from github/staging
Integrating up through commit 5e1bdae
This commit is contained in:
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "AssetDatabaseLocationListener.h"
|
||||
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/AssetDatabase/AssetDatabaseConnection.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
||||
@@ -44,16 +46,20 @@ namespace AssetDatabase
|
||||
return m_assetDatabaseConnection;
|
||||
}
|
||||
|
||||
bool AssetDatabaseLocationListener::GetAssetDatabaseLocation( AZStd::string& result )
|
||||
bool AssetDatabaseLocationListener::GetAssetDatabaseLocation(AZStd::string& result)
|
||||
{
|
||||
result = gEnv->pFileIO->GetAlias( "@devroot@" );
|
||||
result += "/Cache/";
|
||||
ICVar * pCvar = gEnv->pConsole->GetCVar( "sys_game_folder" );
|
||||
if( pCvar && pCvar->GetString() )
|
||||
if (auto registry = AZ::SettingsRegistry::Get(); registry != nullptr)
|
||||
{
|
||||
result += pCvar->GetString();
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectCacheRootValue;
|
||||
if (registry->Get(projectCacheRootValue, AZ::SettingsRegistryMergeUtils::FilePathKey_CacheProjectRootFolder);
|
||||
!projectCacheRootValue.empty())
|
||||
{
|
||||
result = projectCacheRootValue;
|
||||
result += "/assetdb.sqlite";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
result += "/assetdb.sqlite";
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}//namespace AssetDatabase
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#include <QtGui/private/qhighdpiscaling_p.h>
|
||||
#endif
|
||||
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
// AzFramework
|
||||
#if defined(AZ_PLATFORM_WINDOWS)
|
||||
# include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_Platform.h>
|
||||
@@ -267,7 +270,14 @@ namespace Editor
|
||||
QLoggingCategory::setFilterRules(QStringLiteral("lumberyard.editor.input.*=false"));
|
||||
|
||||
// Initialize our stylesheet here to allow Gems to register stylesheets when their system components activate.
|
||||
m_stylesheet->initialize(this);
|
||||
AZ::IO::FixedMaxPath engineRootPath;
|
||||
{
|
||||
// Create a ComponentApplication to initialize the AZ::SystemAllocator and initialize the SettingsRegistry
|
||||
AZ::ComponentApplication application(argc, argv);
|
||||
auto settingsRegistry = AZ::SettingsRegistry::Get();
|
||||
settingsRegistry->Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
|
||||
}
|
||||
m_stylesheet->initialize(this, engineRootPath);
|
||||
}
|
||||
|
||||
void EditorQtApplication::Initialize()
|
||||
|
||||
@@ -52,6 +52,7 @@ AZ_POP_DISABLE_WARNING
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
// AzFramework
|
||||
#include <AzFramework/Components/CameraBus.h>
|
||||
@@ -81,7 +82,6 @@ AZ_POP_DISABLE_WARNING
|
||||
#include <CryCommon/ITimer.h>
|
||||
#include <CryCommon/IPhysics.h>
|
||||
#include <CryCommon/ILevelSystem.h>
|
||||
#include <CryCommon/ParseEngineConfig.h>
|
||||
|
||||
// Editor
|
||||
#include "Settings.h"
|
||||
@@ -683,7 +683,6 @@ public:
|
||||
|
||||
QString dummyString;
|
||||
const std::vector<std::pair<CommandLineStringOption, QString&> > stringOptions = {
|
||||
{{"app-root", "Application Root path override", "app-root"}, m_appRoot},
|
||||
{{"logfile", "File name of the log file to write out to.", "logfile"}, m_logFile},
|
||||
{{"runpythonargs", "Command-line argument string to pass to the python script if --runpython or --runpythontest was used.", "runpythonargs"}, m_pythonArgs},
|
||||
{{"exec", "cfg file to run on startup, used for systems like automation", "exec"}, m_execFile},
|
||||
@@ -691,7 +690,11 @@ public:
|
||||
{{"rhi-device-validation", "Command-line argument to configure rhi validation", "dummyString"}, dummyString },
|
||||
{{"exec_line", "command to run on startup, used for systems like automation", "exec_line"}, m_execLineCmd},
|
||||
{{"regset", "Command-line argument to override settings registry values", "regset"}, dummyString},
|
||||
{{"regdump", "Sets a value within the global settings registry at the JSON pointer path @key with value of @value)", "regdump"}, dummyString}
|
||||
{{"regremove", "Deletes a value within the global settings registry at the JSON pointer path @key", "regremove"}, dummyString},
|
||||
{{"regdump", "Sets a value within the global settings registry at the JSON pointer path @key with value of @value", "regdump"}, dummyString},
|
||||
{{"project-path", "Supplies the path to the project that the Editor should use", "project-path"}, dummyString},
|
||||
{{"engine-path", "Supplies the path to the engine", "engine-path"}, dummyString},
|
||||
{{"project-cache-path", "Path to the project cache", "project-cache-path"}, dummyString},
|
||||
// add dummy entries here to prevent QCommandLineParser error-ing out on cmd line args that will be parsed later
|
||||
};
|
||||
|
||||
@@ -719,7 +722,11 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
parser.process(args);
|
||||
if (!parser.parse(args))
|
||||
{
|
||||
AZ_TracePrintf("QT CommandLine Parser", "QT command line parsing warned with message %s."
|
||||
" Has the QCommandLineParser had these options added to it", parser.errorText().toUtf8().constData());
|
||||
}
|
||||
|
||||
// Get boolean options
|
||||
const int numOptions = options.size();
|
||||
@@ -1217,11 +1224,10 @@ bool CCryEditApp::InitGame()
|
||||
{
|
||||
if (!m_bPreviewMode && !GetIEditor()->IsInMatEditMode())
|
||||
{
|
||||
ICVar* pVar = gEnv->pConsole->GetCVar("sys_game_folder");
|
||||
const char* sGameFolder = pVar ? pVar->GetString() : nullptr;
|
||||
Log((QString("sys_game_folder = ") + (sGameFolder && sGameFolder[0] ? sGameFolder : "<not set>")).toUtf8().data());
|
||||
AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
|
||||
Log((QString("project_path = %1").arg(!projectPath.empty() ? projectPath.c_str() : "<not set>")).toUtf8().data());
|
||||
|
||||
pVar = gEnv->pConsole->GetCVar("sys_localization_folder");
|
||||
ICVar* pVar = gEnv->pConsole->GetCVar("sys_localization_folder");
|
||||
const char* sLocalizationFolder = pVar ? pVar->GetString() : nullptr;
|
||||
Log((QString("sys_localization_folder = ") + (sLocalizationFolder && sLocalizationFolder[0] ? sLocalizationFolder : "<not set>")).toUtf8().data());
|
||||
|
||||
@@ -1740,11 +1746,17 @@ BOOL CCryEditApp::InitInstance()
|
||||
mainWindowWrapper->setGuest(mainWindow);
|
||||
HWND mainWindowWrapperHwnd = (HWND)mainWindowWrapper->winId();
|
||||
|
||||
QDir engineRoot = AzQtComponents::FindEngineRootDir(qApp);
|
||||
AZ::IO::FixedMaxPath engineRootPath;
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
settingsRegistry->Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
|
||||
}
|
||||
QDir engineRoot = QString::fromUtf8(engineRootPath.c_str(), aznumeric_cast<int>(engineRootPath.Native().size()));
|
||||
AzQtComponents::StyleManager::addSearchPaths(
|
||||
QStringLiteral("style"),
|
||||
engineRoot.filePath(QStringLiteral("Code/Sandbox/Editor/Style")),
|
||||
QStringLiteral(":/Editor/Style"));
|
||||
QStringLiteral(":/Editor/Style"),
|
||||
engineRootPath);
|
||||
AzQtComponents::StyleManager::setStyleSheet(mainWindow, QStringLiteral("style:Editor.qss"));
|
||||
|
||||
// Note: we should use getNativeHandle to get the HWND from the widget, but
|
||||
@@ -5496,9 +5508,9 @@ void CCryEditApp::OpenLUAEditor(const char* files)
|
||||
}
|
||||
}
|
||||
|
||||
const char* appRoot = nullptr;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(appRoot, &AzFramework::ApplicationRequests::GetAppRoot);
|
||||
AZ_Assert(appRoot != nullptr, "Unable to communicate to AzFramework::ApplicationRequests::Bus");
|
||||
const char* engineRoot = nullptr;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(engineRoot, &AzFramework::ApplicationRequests::GetEngineRoot);
|
||||
AZ_Assert(engineRoot != nullptr, "Unable to communicate to AzFramework::ApplicationRequests::Bus");
|
||||
|
||||
AZStd::string_view exePath;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(exePath, &AZ::ComponentApplicationRequests::GetExecutableFolder);
|
||||
@@ -5509,7 +5521,7 @@ void CCryEditApp::OpenLUAEditor(const char* files)
|
||||
#endif
|
||||
"\"", aznumeric_cast<int>(exePath.size()), exePath.data());
|
||||
|
||||
AZStd::string processArgs = AZStd::string::format("%s -app-root \"%s\"", args.c_str(), appRoot);
|
||||
AZStd::string processArgs = AZStd::string::format("%s -engine-path \"%s\"", args.c_str(), engineRoot);
|
||||
StartProcessDetached(process.c_str(), processArgs.c_str());
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <AzCore/Module/Module.h> // for AZ::ModuleData
|
||||
#include <AzCore/Module/ModuleManagerBus.h> // for AZ::ModuleManagerRequestBus
|
||||
#include <AzCore/Module/DynamicModuleHandle.h> // for AZ::DynamicModuleHandle
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/API/ViewPaneOptions.h> // for AzToolsFramework::ViewPaneOptions
|
||||
@@ -88,26 +90,64 @@ CPythonScriptsDialog::CPythonScriptsDialog(QWidget* parent)
|
||||
}
|
||||
}
|
||||
|
||||
ScanFolderForScripts(QString("@devroot@/%1/Editor/Scripts").arg(GetIEditor()->GetProjectName()), scriptFolders);
|
||||
AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
|
||||
ScanFolderForScripts(QString("%1/Editor/Scripts").arg(projectPath.c_str()), scriptFolders);
|
||||
|
||||
auto moduleCallback = [this, &scriptFolders](const AZ::ModuleData& moduleData) -> bool
|
||||
struct GetGemSourcePathsVisitor
|
||||
: AZ::SettingsRegistryInterface::Visitor
|
||||
{
|
||||
if (moduleData.GetDynamicModuleHandle())
|
||||
GetGemSourcePathsVisitor(AZ::SettingsRegistryInterface& settingsRegistry)
|
||||
: m_settingsRegistry(settingsRegistry)
|
||||
{}
|
||||
void Visit(AZStd::string_view path, AZStd::string_view, AZ::SettingsRegistryInterface::Type,
|
||||
AZStd::string_view value) override
|
||||
{
|
||||
const AZ::OSString& modulePath = moduleData.GetDynamicModuleHandle()->GetFilename();
|
||||
AZStd::string fileName;
|
||||
AzFramework::StringFunc::Path::GetFileName(modulePath.c_str(), fileName);
|
||||
|
||||
AZStd::vector<AZStd::string> tokens;
|
||||
AzFramework::StringFunc::Tokenize(fileName.c_str(), tokens, '.');
|
||||
if (tokens.size() > 2 && tokens[0] == "Gem")
|
||||
AZStd::string_view jsonSourcePathPointer{ path };
|
||||
// Remove the array index from the path and check if the JSON path ends with "/SourcePaths"
|
||||
AZ::StringFunc::TokenizeLast(jsonSourcePathPointer, "/");
|
||||
if (jsonSourcePathPointer.ends_with("/SourcePaths"))
|
||||
{
|
||||
ScanFolderForScripts(QString("@engroot@/Gems/%1/Editor/Scripts").arg(tokens[1].c_str()), scriptFolders);
|
||||
AZ::IO::Path newSourcePath = jsonSourcePathPointer;
|
||||
// Resolve any file aliases first - Do not use ResolvePath() as that assumes
|
||||
// any relative path is underneath the @assets@ alias
|
||||
if (auto fileIoBase = AZ::IO::FileIOBase::GetInstance(); fileIoBase != nullptr)
|
||||
{
|
||||
AZ::IO::FixedMaxPath replacedAliasPath;
|
||||
if (fileIoBase->ReplaceAlias(replacedAliasPath, value))
|
||||
{
|
||||
newSourcePath = AZ::IO::PathView(replacedAliasPath);
|
||||
}
|
||||
}
|
||||
|
||||
// The current assumption is that the gem source path is the relative to the engine root
|
||||
AZ::IO::Path engineRootPath;
|
||||
m_settingsRegistry.Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
|
||||
newSourcePath = (engineRootPath / newSourcePath).LexicallyNormal();
|
||||
|
||||
if (auto gemSourcePathIter = AZStd::find(m_gemSourcePaths.begin(), m_gemSourcePaths.end(), newSourcePath);
|
||||
gemSourcePathIter == m_gemSourcePaths.end())
|
||||
{
|
||||
m_gemSourcePaths.emplace_back(AZStd::move(newSourcePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
AZStd::vector<AZ::IO::Path> m_gemSourcePaths;
|
||||
private:
|
||||
AZ::SettingsRegistryInterface& m_settingsRegistry;
|
||||
};
|
||||
AZ::ModuleManagerRequestBus::Broadcast(&AZ::ModuleManagerRequestBus::Events::EnumerateModules, moduleCallback);
|
||||
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
GetGemSourcePathsVisitor visitor{ *settingsRegistry };
|
||||
constexpr auto gemListKey = AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::OrganizationRootKey)
|
||||
+ "/Gems";
|
||||
settingsRegistry->Visit(visitor, gemListKey);
|
||||
for (const AZ::IO::Path& gemSourcePath : visitor.m_gemSourcePaths)
|
||||
{
|
||||
ScanFolderForScripts(QString("%1/Editor/Scripts").arg(gemSourcePath.c_str()), scriptFolders);
|
||||
}
|
||||
}
|
||||
|
||||
ui->treeView->init(scriptFolders, s_kPythonFileNameSpec, s_kRootElementName, false, false);
|
||||
QObject::connect(ui->treeView, &CFolderTreeCtrl::ItemDoubleClicked, this, &CPythonScriptsDialog::OnExecute);
|
||||
|
||||
@@ -23,9 +23,6 @@
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserComponent.h>
|
||||
#include <AzToolsFramework/MaterialBrowser/MaterialBrowserComponent.h>
|
||||
|
||||
// CryCommon
|
||||
#include <CryCommon/ParseEngineConfig.h>
|
||||
|
||||
// Editor
|
||||
#include "MainWindow.h"
|
||||
#include "CryEdit.h"
|
||||
@@ -109,15 +106,6 @@ namespace EditorInternal
|
||||
{
|
||||
AzFramework::Application::StartupParameters params;
|
||||
|
||||
AZStd::string appRootOverride;
|
||||
const size_t appRootSwitches = m_commandLine.GetNumSwitchValues("app-root");
|
||||
if (appRootSwitches != 0)
|
||||
{
|
||||
// Use the last --app-root parameter specified on the command line
|
||||
appRootOverride = m_commandLine.GetSwitchValue("app-root", appRootSwitches - 1);
|
||||
params.m_appRootOverride = appRootOverride.c_str();
|
||||
}
|
||||
|
||||
// Must be done before creating QApplication, otherwise asserts when we alloc
|
||||
AzToolsFramework::ToolsApplication::Start({}, params);
|
||||
if (IsStartupAborted() || !m_systemEntity)
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
#include <CryCommon/IDeferredCollisionEvent.h>
|
||||
#include <CryCommon/ITimeOfDay.h>
|
||||
#include <CryCommon/LyShine/ILyShine.h>
|
||||
#include <CryCommon/ParseEngineConfig.h>
|
||||
#include <CryCommon/MainThreadRenderRequestBus.h>
|
||||
|
||||
// Editor
|
||||
@@ -415,24 +414,7 @@ AZ::Outcome<void, AZStd::string> CGameEngine::Init(
|
||||
(PFNCREATESYSTEMINTERFACE)CryGetProcAddress(m_hSystemHandle, "CreateSystemInterface");
|
||||
|
||||
|
||||
// Locate the root path
|
||||
const char* calcRootPath = nullptr;
|
||||
EBUS_EVENT_RESULT(calcRootPath, AZ::ComponentApplicationBus, GetAppRoot);
|
||||
if (calcRootPath == nullptr)
|
||||
{
|
||||
// If the app root isnt available, default to the engine root
|
||||
EBUS_EVENT_RESULT(calcRootPath, AzToolsFramework::ToolsApplicationRequestBus, GetEngineRootPath);
|
||||
}
|
||||
const char* searchPath[] = { calcRootPath };
|
||||
CEngineConfig engineConfig(searchPath,AZ_ARRAY_SIZE(searchPath)); // read the engine config also to see what game is running, and what folder(s) there are.
|
||||
|
||||
SSystemInitParams sip;
|
||||
engineConfig.CopyToStartupParams(sip);
|
||||
|
||||
sip.connectToRemote = true; // editor always connects
|
||||
sip.waitForConnection = true; // editor REQUIRES connect.
|
||||
const char localIP[10] = "127.0.0.1";
|
||||
azstrncpy(sip.remoteIP, AZ_ARRAY_SIZE(sip.remoteIP), localIP, AZ_ARRAY_SIZE(localIP)); // editor ONLY connects to the local asset processor
|
||||
|
||||
sip.bEditor = true;
|
||||
sip.bDedicatedServer = false;
|
||||
@@ -457,15 +439,6 @@ AZ::Outcome<void, AZStd::string> CGameEngine::Init(
|
||||
sip.pUserCallback = m_pSystemUserCallback;
|
||||
sip.pValidator = GetIEditor()->GetErrorReport(); // Assign validator from Editor.
|
||||
|
||||
// Calculate the branch token first based on the app root path if possible
|
||||
if (calcRootPath!=nullptr)
|
||||
{
|
||||
AZStd::string appRoot(calcRootPath);
|
||||
AZStd::string branchToken;
|
||||
AzFramework::StringFunc::AssetPath::CalculateBranchToken(appRoot, branchToken);
|
||||
azstrncpy(sip.branchToken, AZ_ARRAY_SIZE(sip.branchToken), branchToken.c_str(), branchToken.length());
|
||||
}
|
||||
|
||||
if (sInCmdLine)
|
||||
{
|
||||
azstrncpy(sip.szSystemCmdLine, AZ_COMMAND_LINE_LEN, sInCmdLine, AZ_COMMAND_LINE_LEN);
|
||||
@@ -484,7 +457,7 @@ AZ::Outcome<void, AZStd::string> CGameEngine::Init(
|
||||
{
|
||||
sip.bSkipFont = true;
|
||||
}
|
||||
AssetProcessConnectionStatus apConnectionStatus;
|
||||
AssetProcessConnectionStatus apConnectionStatus;
|
||||
|
||||
m_pISystem = pfnCreateSystemInterface(sip);
|
||||
|
||||
@@ -512,33 +485,16 @@ AZ::Outcome<void, AZStd::string> CGameEngine::Init(
|
||||
|
||||
if (apConnectionStatus.CheckConnectionFailed())
|
||||
{
|
||||
AzFramework::AssetSystem::ConnectionSettings connectionSettings;
|
||||
AzFramework::AssetSystem::ReadConnectionSettingsFromSettingsRegistry(connectionSettings);
|
||||
auto errorMessage = AZStd::string::format("Unable to connect to the local Asset Processor.\n\n"
|
||||
"The Asset Processor is either not running locally or not accepting connections on port %d. "
|
||||
"The Asset Processor is either not running locally or not accepting connections on port %hu. "
|
||||
"Check your remote_port settings in bootstrap.cfg or view the Asset Processor's \"Logs\" tab "
|
||||
"for any errors.", sip.remotePort);
|
||||
"for any errors.", connectionSettings.m_assetProcessorPort);
|
||||
gEnv = nullptr;
|
||||
return AZ::Failure(errorMessage);
|
||||
}
|
||||
|
||||
// because we're the editor here, we also give tool aliases to the original, unaltered roots:
|
||||
string devAssetsFolder = engineConfig.m_rootFolder + "/" + engineConfig.m_gameFolder;
|
||||
if (gEnv && gEnv->pFileIO)
|
||||
{
|
||||
const char* engineRoot = nullptr;
|
||||
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(engineRoot, &AzToolsFramework::ToolsApplicationRequests::GetEngineRootPath);
|
||||
if (engineRoot != nullptr)
|
||||
{
|
||||
gEnv->pFileIO->SetAlias("@engroot@", engineRoot);
|
||||
}
|
||||
else
|
||||
{
|
||||
gEnv->pFileIO->SetAlias("@engroot@", engineConfig.m_rootFolder.c_str());
|
||||
}
|
||||
|
||||
gEnv->pFileIO->SetAlias("@devroot@", engineConfig.m_rootFolder.c_str());
|
||||
gEnv->pFileIO->SetAlias("@devassets@", devAssetsFolder.c_str());
|
||||
}
|
||||
|
||||
SetEditorCoreEnvironment(gEnv);
|
||||
|
||||
if (gEnv
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <QFontMetrics>
|
||||
#include <QSettings>
|
||||
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
// AzFramework
|
||||
#include <AzFramework/IO/LocalFileIO.h>
|
||||
#include <AzQtComponents/Components/Widgets/PushButton.h>
|
||||
@@ -975,8 +977,9 @@ void GraphicsSettingsDialog::accept()
|
||||
|
||||
void GraphicsSettingsDialog::OpenCustomSpecDialog()
|
||||
{
|
||||
QString projectName = GetIEditor()->GetProjectName();
|
||||
QString settingsPath = projectName + "/" + SETTINGS_FILE_PATH;
|
||||
AZ::IO::FixedMaxPath projectPath = AZ::Utils::GetProjectPath();
|
||||
projectPath /= SETTINGS_FILE_PATH.toUtf8().constData();
|
||||
QString settingsPath = QString::fromUtf8(projectPath.c_str(), aznumeric_cast<int>(projectPath.Native().size()));
|
||||
|
||||
CAutoDirectoryRestoreFileDialog importCustomSpecDialog(QFileDialog::AcceptOpen, QFileDialog::ExistingFile, ".cfg", settingsPath, CFG_FILEFILTER, {}, {}, this);
|
||||
|
||||
@@ -1189,8 +1192,9 @@ void GraphicsSettingsDialog::SaveSystemSettings()
|
||||
|
||||
// Adding the project name to the path so that the file is created there if it doesn't already exist
|
||||
// as we don't want to modify the version in Engine/config.
|
||||
QString projectName = GetIEditor()->GetProjectName();
|
||||
QString settingsPath = projectName + "/" + SETTINGS_FILE_PATH;
|
||||
AZ::IO::FixedMaxPath projectPath = AZ::Utils::GetProjectPath();
|
||||
projectPath /= SETTINGS_FILE_PATH.toUtf8().constData();
|
||||
QString settingsPath = QString::fromUtf8(projectPath.c_str(), aznumeric_cast<int>(projectPath.Native().size()));
|
||||
|
||||
QString settingsFile = settingsPath + m_cfgFiles[m_currentPlatform][cfgFileIndex].c_str();
|
||||
|
||||
|
||||
@@ -516,8 +516,6 @@ struct IEditor
|
||||
virtual QString GetSearchPath(EEditorPathName path) = 0;
|
||||
//! This folder is supposed to store Sandbox user settings and state
|
||||
virtual QString GetResolvedUserFolder() = 0;
|
||||
//! Returns the name of the sys_game_folder
|
||||
virtual QString GetProjectName() = 0;
|
||||
//! Execute application and get console output.
|
||||
virtual bool ExecuteConsoleApp(
|
||||
const QString& CommandLine,
|
||||
|
||||
@@ -655,17 +655,6 @@ QString CEditorImpl::GetResolvedUserFolder()
|
||||
return m_userFolder;
|
||||
}
|
||||
|
||||
QString CEditorImpl::GetProjectName()
|
||||
{
|
||||
ICVar* pCVar = (gEnv && gEnv->pConsole) ? gEnv->pConsole->GetCVar("sys_game_folder") : nullptr;
|
||||
if (pCVar && pCVar->GetString())
|
||||
{
|
||||
return QString(pCVar->GetString());
|
||||
}
|
||||
|
||||
return tr("unknown");
|
||||
}
|
||||
|
||||
void CEditorImpl::SetDataModified()
|
||||
{
|
||||
GetDocument()->SetModifiedFlag(TRUE);
|
||||
|
||||
@@ -146,7 +146,6 @@ public:
|
||||
QString GetLevelDataFolder();
|
||||
QString GetSearchPath(EEditorPathName path);
|
||||
QString GetResolvedUserFolder();
|
||||
QString GetProjectName() override;
|
||||
bool ExecuteConsoleApp(const QString& CommandLine, QString& OutputText, bool bNoTimeOut = false, bool bShowWindow = false);
|
||||
virtual bool IsInGameMode() override;
|
||||
virtual void SetInGameMode(bool inGame) override;
|
||||
|
||||
@@ -61,7 +61,6 @@ public:
|
||||
MOCK_METHOD0(GetLevelDataFolder, QString());
|
||||
MOCK_METHOD1(GetPrimaryCDFolder, QString(EEditorPathName));
|
||||
MOCK_METHOD0(GetResolvedUserFolder, QString());
|
||||
MOCK_METHOD0(GetProjectName, QString());
|
||||
MOCK_METHOD4(ExecuteConsoleApp, bool(const QString&,QString&,bool,bool));
|
||||
MOCK_METHOD0(SetDataModified, void());
|
||||
MOCK_CONST_METHOD0(IsInitialized, bool());
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "MainStatusBar.h"
|
||||
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
// AzQtComponents
|
||||
#include <AzQtComponents/Components/Widgets/CheckBox.h>
|
||||
#include <AzQtComponents/Components/Style.h>
|
||||
@@ -220,24 +221,16 @@ MainStatusBar::MainStatusBar(QWidget* parent)
|
||||
void MainStatusBar::Init()
|
||||
{
|
||||
//called on mainwindow initialization
|
||||
const int statusbarTimerUpdateInterval {
|
||||
const int statusbarTimerUpdateInterval{
|
||||
500
|
||||
}; //in ms, so 2 FPS
|
||||
|
||||
AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
|
||||
QString strGameInfo;
|
||||
ICVar* pCVar = gEnv->pConsole->GetCVar("sys_game_folder");
|
||||
if (pCVar)
|
||||
{
|
||||
strGameInfo = tr("GameFolder: '%1'").arg(QtUtil::ToQString(pCVar->GetString()));
|
||||
}
|
||||
pCVar = gEnv->pConsole->GetCVar("sys_dll_game");
|
||||
if (pCVar)
|
||||
{
|
||||
strGameInfo += QLatin1String(" - ") + tr("GameDLL: '%1'").arg(QtUtil::ToQString(pCVar->GetString()));
|
||||
}
|
||||
strGameInfo = tr("GameFolder: '%1'").arg(projectPath.c_str());
|
||||
SetItem(QStringLiteral("game_info"), strGameInfo, tr("Game Info"), QPixmap());
|
||||
|
||||
//ask for updates for items regulary. This is basically what MFC does
|
||||
//ask for updates for items regularly. This is basically what MFC does
|
||||
auto timer = new QTimer(this);
|
||||
timer->setInterval(statusbarTimerUpdateInterval);
|
||||
connect(timer, &QTimer::timeout, this, &MainStatusBar::requestStatusUpdate);
|
||||
|
||||
@@ -24,9 +24,8 @@
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/Settings/SettingsRegistry.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
|
||||
// AzFramework
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/SourceControl/SourceControlAPI.h>
|
||||
@@ -997,7 +996,7 @@ void SEditorSettings::LoadDefaultGamePaths()
|
||||
}
|
||||
|
||||
AZStd::string iconsPath;
|
||||
AzFramework::StringFunc::Path::Join(Path::GetEditingRootFolder().c_str(), "Editor/UI/Icons", iconsPath);
|
||||
AZ::StringFunc::Path::Join(Path::GetEditingRootFolder().c_str(), "Editor/UI/Icons", iconsPath);
|
||||
searchPaths[EDITOR_PATH_UI_ICONS].push_back(iconsPath.c_str());
|
||||
}
|
||||
|
||||
@@ -1166,34 +1165,28 @@ AzToolsFramework::EditorSettingsAPIRequests::SettingOutcome SEditorSettings::Set
|
||||
|
||||
void SEditorSettings::SaveSettingsRegistryFile()
|
||||
{
|
||||
auto fileIo = AZ::IO::FileIOBase::GetInstance();
|
||||
|
||||
// Resolve path to editorpreferences.setreg
|
||||
AZ::IO::FixedMaxPath editorPreferencesFilePath = "user/Registry/editorpreferences.setreg";
|
||||
if (fileIo == nullptr || !fileIo->ResolvePath(editorPreferencesFilePath, "@devroot@/user/Registry/editorpreferences.setreg"))
|
||||
auto registry = AZ::SettingsRegistry::Get();
|
||||
if (registry == nullptr)
|
||||
{
|
||||
AZ_Warning("SEditorSettings", false, R"(Unable to resolve path "%s" to the Editor Preferences registry file\n)",
|
||||
editorPreferencesFilePath.c_str());
|
||||
AZ_Warning("SEditorSettings", false, "Unable to access global settings registry. Editor Preferences cannot be saved");
|
||||
return;
|
||||
}
|
||||
|
||||
// Resolve path to editorpreferences.setreg
|
||||
AZ::IO::FixedMaxPath editorPreferencesFilePath = AZ::Utils::GetProjectPath();
|
||||
editorPreferencesFilePath /= "user/Registry/editorpreferences.setreg";
|
||||
|
||||
AZ::SettingsRegistryMergeUtils::DumperSettings dumperSettings;
|
||||
dumperSettings.m_prettifyOutput = true;
|
||||
dumperSettings.m_includeFilter = [](AZStd::string_view path)
|
||||
{
|
||||
AZStd::string_view prefixPath("/Amazon/Editor/Preferences");
|
||||
return prefixPath.starts_with(path.substr(0, prefixPath.size()));
|
||||
};
|
||||
dumperSettings.m_jsonPointerPrefix = "/Amazon/Editor/Preferences";
|
||||
|
||||
AZStd::string stringBuffer;
|
||||
if (auto registry = AZ::SettingsRegistry::Get(); registry != nullptr)
|
||||
AZ::IO::ByteContainerStream stringStream(&stringBuffer);
|
||||
if (!AZ::SettingsRegistryMergeUtils::DumpSettingsRegistryToStream(*registry, "/Amazon/Editor/Preferences", stringStream, dumperSettings))
|
||||
{
|
||||
AZ::IO::ByteContainerStream stringStream(&stringBuffer);
|
||||
if (!AZ::SettingsRegistryMergeUtils::DumpSettingsRegistryToStream(*registry, "", stringStream, dumperSettings))
|
||||
{
|
||||
AZ_Warning("SEditorSettings", false, R"(Unable to save changes to the Editor Preferences registry file at "%s"\n)",
|
||||
editorPreferencesFilePath.c_str());
|
||||
return;
|
||||
}
|
||||
AZ_Warning("SEditorSettings", false, R"(Unable to save changes to the Editor Preferences registry file at "%s"\n)",
|
||||
editorPreferencesFilePath.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
bool saved{};
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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 "AtomOutputFrameCapture.h"
|
||||
|
||||
#include <Atom/RPI.Public/Pass/Specific/RenderToTexturePass.h>
|
||||
#include <Atom/RPI.Public/RenderPipeline.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
#include <Atom/RPI.Reflect/System/RenderPipelineDescriptor.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Math/MatrixUtils.h>
|
||||
#include <AzCore/Name/Name.h>
|
||||
#include <AzFramework/Entity/GameEntityContextBus.h>
|
||||
#include <AzFramework/Scene/Scene.h>
|
||||
#include <AzFramework/Scene/SceneSystemBus.h>
|
||||
|
||||
namespace TrackView
|
||||
{
|
||||
void AtomOutputFrameCapture::CreatePipeline(
|
||||
AZ::RPI::Scene& scene, const AZStd::string& pipelineName, const uint32_t width, const uint32_t height)
|
||||
{
|
||||
AZ::RPI::RenderPipelineDescriptor pipelineDesc;
|
||||
pipelineDesc.m_mainViewTagName = "MainCamera"; // must be "MainCamera"
|
||||
pipelineDesc.m_name = pipelineName;
|
||||
pipelineDesc.m_rootPassTemplate = "MainPipelineRenderToTexture";
|
||||
pipelineDesc.m_renderSettings.m_multisampleState.m_samples = 4;
|
||||
m_renderPipeline = AZ::RPI::RenderPipeline::CreateRenderPipeline(pipelineDesc);
|
||||
|
||||
if (auto renderToTexturePass = azrtti_cast<AZ::RPI::RenderToTexturePass*>(m_renderPipeline->GetRootPass().get()))
|
||||
{
|
||||
renderToTexturePass->ResizeOutput(width, height);
|
||||
}
|
||||
|
||||
scene.AddRenderPipeline(m_renderPipeline);
|
||||
|
||||
// rendering pipeline has a tree structure
|
||||
m_passHierarchy.push_back(pipelineName);
|
||||
m_passHierarchy.push_back("CopyToSwapChain");
|
||||
|
||||
// retrieve View from the camera that's animating
|
||||
AZ::Name viewName = AZ::Name("MainCamera");
|
||||
m_view = AZ::RPI::View::CreateView(viewName, AZ::RPI::View::UsageCamera);
|
||||
m_renderPipeline->SetDefaultView(m_view);
|
||||
}
|
||||
|
||||
void AtomOutputFrameCapture::DestroyPipeline(AZ::RPI::Scene& scene)
|
||||
{
|
||||
scene.RemoveRenderPipeline(m_renderPipeline->GetId());
|
||||
m_passHierarchy.clear();
|
||||
m_renderPipeline.reset();
|
||||
m_view.reset();
|
||||
}
|
||||
|
||||
void AtomOutputFrameCapture::UpdateView(const AZ::Matrix3x4& cameraTransform, const AZ::Matrix4x4& cameraProjection)
|
||||
{
|
||||
m_view->SetCameraTransform(cameraTransform);
|
||||
m_view->SetViewToClipMatrix(cameraProjection);
|
||||
}
|
||||
|
||||
bool AtomOutputFrameCapture::BeginCapture(
|
||||
const AZ::RPI::AttachmentReadback::CallbackFunction& attachmentReadbackCallback, CaptureFinishedCallback captureFinishedCallback)
|
||||
{
|
||||
AZ::Render::FrameCaptureNotificationBus::Handler::BusConnect();
|
||||
|
||||
m_captureFinishedCallback = AZStd::move(captureFinishedCallback);
|
||||
|
||||
// note: "Output" (slot name) maps to MainPipeline.pass CopyToSwapChain
|
||||
bool startedCapture = false;
|
||||
AZ::Render::FrameCaptureRequestBus::BroadcastResult(
|
||||
startedCapture, &AZ::Render::FrameCaptureRequestBus::Events::CapturePassAttachmentWithCallback, m_passHierarchy,
|
||||
AZStd::string("Output"), attachmentReadbackCallback);
|
||||
|
||||
return startedCapture;
|
||||
}
|
||||
|
||||
void AtomOutputFrameCapture::OnCaptureFinished(
|
||||
[[maybe_unused]] AZ::Render::FrameCaptureResult result, [[maybe_unused]] const AZStd::string& info)
|
||||
{
|
||||
m_captureFinishedCallback();
|
||||
AZ::Render::FrameCaptureNotificationBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
AZ::Matrix3x4 TransformFromEntityId(const AZ::EntityId entityId)
|
||||
{
|
||||
AZ::Transform cameraTransform = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(cameraTransform, entityId, &AZ::TransformBus::Events::GetWorldTM);
|
||||
return AZ::Matrix3x4::CreateFromTransform(cameraTransform);
|
||||
}
|
||||
|
||||
AZ::Matrix4x4 ProjectionFromCameraEntityId(const AZ::EntityId entityId, const float outputWidth, const float outputHeight)
|
||||
{
|
||||
float nearDist = 0.0f;
|
||||
Camera::CameraRequestBus::EventResult(nearDist, entityId, &Camera::CameraRequestBus::Events::GetNearClipDistance);
|
||||
float farDist = 0.0f;
|
||||
Camera::CameraRequestBus::EventResult(farDist, entityId, &Camera::CameraRequestBus::Events::GetFarClipDistance);
|
||||
float fovRad = 0.0f;
|
||||
Camera::CameraRequestBus::EventResult(fovRad, entityId, &Camera::CameraRequestBus::Events::GetFovRadians);
|
||||
|
||||
const float aspectRatio = outputWidth / outputHeight;
|
||||
|
||||
AZ::Matrix4x4 viewToClipMatrix;
|
||||
AZ::MakePerspectiveFovMatrixRH(viewToClipMatrix, fovRad, aspectRatio, nearDist, farDist, /*reverseDepth=*/true);
|
||||
return viewToClipMatrix;
|
||||
}
|
||||
|
||||
AZ::RPI::Scene* SceneFromGameEntityContext()
|
||||
{
|
||||
AzFramework::EntityContextId entityContextId;
|
||||
AzFramework::GameEntityContextRequestBus::BroadcastResult(
|
||||
entityContextId, &AzFramework::GameEntityContextRequestBus::Events::GetGameEntityContextId);
|
||||
|
||||
return AZ::RPI::Scene::GetSceneForEntityContextId(entityContextId);
|
||||
}
|
||||
} // namespace TrackView
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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 <Atom/Feature/Utils/FrameCaptureBus.h>
|
||||
#include <AzFramework/Components/CameraBus.h>
|
||||
|
||||
namespace TrackView
|
||||
{
|
||||
//! Provides functionality to capture frames from the "MainCamera".
|
||||
//! A new pipeline is created (and associated with the scene provided), a callback can be
|
||||
//! provided to handle the attachment readback (what to do with the captured frame) and also
|
||||
//! what to do after an individual capture fully completes (called in OnCaptureFinished).
|
||||
class AtomOutputFrameCapture : private AZ::Render::FrameCaptureNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
AtomOutputFrameCapture() = default;
|
||||
|
||||
using CaptureFinishedCallback = AZStd::function<void()>;
|
||||
|
||||
//! Create a new pipeline associated with a given scene.
|
||||
//! @note "MainCamera" is the view that is captured.
|
||||
void CreatePipeline(AZ::RPI::Scene& scene, const AZStd::string& pipelineName, uint32_t width, uint32_t height);
|
||||
//! Removes the pipeline from the scene provided and then destroys it.
|
||||
//! @note scene must be the same scene used to create the pipeline.
|
||||
void DestroyPipeline(AZ::RPI::Scene& scene);
|
||||
|
||||
//! Request a capture to start.
|
||||
//! @param attachmentReadbackCallback Handles the returned attachment (image data returned by the renderer).
|
||||
//! @param captureFinishedCallback Logic to run once the capture has completed fully.
|
||||
bool BeginCapture(
|
||||
const AZ::RPI::AttachmentReadback::CallbackFunction& attachmentReadbackCallback,
|
||||
CaptureFinishedCallback captureFinishedCallback);
|
||||
|
||||
//! Update the internal view that is associated with the created pipeline.
|
||||
void UpdateView(const AZ::Matrix3x4& cameraTransform, const AZ::Matrix4x4& cameraProjection);
|
||||
|
||||
private:
|
||||
AZ::RPI::RenderPipelinePtr m_renderPipeline; //!< The internal render pipeline.
|
||||
AZ::RPI::ViewPtr m_view; //!< The view associated with the render pipeline.
|
||||
AZStd::vector<AZStd::string> m_passHierarchy; //!< Pass hierarchy (includes pipelineName and CopyToSwapChain).
|
||||
CaptureFinishedCallback m_captureFinishedCallback; //!< Stored callback called from OnCaptureFinished.
|
||||
|
||||
// FrameCaptureNotificationBus overrides ...
|
||||
void OnCaptureFinished(AZ::Render::FrameCaptureResult result, const AZStd::string& info) override;
|
||||
};
|
||||
|
||||
inline AZ::EntityId ActiveCameraEntityId()
|
||||
{
|
||||
AZ::EntityId activeCameraId;
|
||||
Camera::CameraSystemRequestBus::BroadcastResult(activeCameraId, &Camera::CameraSystemRequests::GetActiveCamera);
|
||||
return activeCameraId;
|
||||
}
|
||||
|
||||
//! Returns the transform for the given EntityId.
|
||||
AZ::Matrix3x4 TransformFromEntityId(AZ::EntityId entityId);
|
||||
|
||||
//! Returns the projection matrix for the given camera EntityId.
|
||||
//! @note Must provide a valid camera entity.
|
||||
AZ::Matrix4x4 ProjectionFromCameraEntityId(AZ::EntityId entityId, float outputWidth, float outputHeight);
|
||||
|
||||
//! Helper to return the GameEntityContext scene.
|
||||
AZ::RPI::Scene* SceneFromGameEntityContext();
|
||||
} // namespace TrackView
|
||||
@@ -43,7 +43,6 @@ AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#include <TrackView/ui_SequenceBatchRenderDialog.h>
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
const int g_useActiveViewportResolution = -1; // reserved value to indicate the use of the active viewport resolution
|
||||
@@ -92,6 +91,14 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateAtomOutputFrameCaptureView(TrackView::AtomOutputFrameCapture& atomOutputFrameCapture, const int width, const int height)
|
||||
{
|
||||
const AZ::EntityId activeCameraEntityId = TrackView::ActiveCameraEntityId();
|
||||
atomOutputFrameCapture.UpdateView(
|
||||
TrackView::TransformFromEntityId(activeCameraEntityId),
|
||||
TrackView::ProjectionFromCameraEntityId(activeCameraEntityId, width, height));
|
||||
}
|
||||
|
||||
CSequenceBatchRenderDialog::CSequenceBatchRenderDialog(float fps, QWidget* pParent /* = nullptr */)
|
||||
: QDialog(pParent)
|
||||
, m_fpsForTimeToFrameConversion(fps)
|
||||
@@ -874,8 +881,6 @@ void CSequenceBatchRenderDialog::InitializeContext()
|
||||
|
||||
void CSequenceBatchRenderDialog::CaptureItemStart()
|
||||
{
|
||||
AZ::Render::FrameCaptureNotificationBus::Handler::BusConnect();
|
||||
|
||||
// Disable most of the UI in group chunks.
|
||||
// (Leave the start/cancel button and feedback elements).
|
||||
m_ui->BATCH_RENDER_LIST_GROUP_BOX->setEnabled(false);
|
||||
@@ -976,20 +981,11 @@ void CSequenceBatchRenderDialog::CaptureItemStart()
|
||||
m_renderContext.cvarCustomResHeightBU = pCVarCustomResHeight->GetIVal();
|
||||
pCVarCustomResWidth->Set(renderWidth);
|
||||
pCVarCustomResHeight->Set(renderHeight);
|
||||
|
||||
// awaiting ATOM-14859
|
||||
// AzFramework::NativeWindowHandle windowHandle = nullptr;
|
||||
// AzFramework::WindowSystemRequestBus::BroadcastResult(
|
||||
// windowHandle, &AzFramework::WindowSystemRequestBus::Events::GetDefaultWindowHandle);
|
||||
// AzFramework::WindowRequestBus::Event(
|
||||
// windowHandle, &AzFramework::WindowRequestBus::Events::ResizeClientArea,
|
||||
// AzFramework::WindowSize(renderWidth, renderHeight));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, try to adjust the viewport resolution accordingly.
|
||||
CLayoutViewPane* viewPane = MainWindow::instance()->GetActiveView();
|
||||
if (viewPane)
|
||||
if (CLayoutViewPane* viewPane = MainWindow::instance()->GetActiveView())
|
||||
{
|
||||
viewPane->ResizeViewport(renderWidth, renderHeight);
|
||||
}
|
||||
@@ -1008,6 +1004,11 @@ void CSequenceBatchRenderDialog::CaptureItemStart()
|
||||
}
|
||||
}
|
||||
|
||||
// create a new atom pipeline to capture the frames of the current sequence
|
||||
m_atomOutputFrameCapture.CreatePipeline(
|
||||
*TrackView::SceneFromGameEntityContext(), "TrackViewSequencePipeline", renderItem.resW, renderItem.resH);
|
||||
UpdateAtomOutputFrameCaptureView(m_atomOutputFrameCapture, renderItem.resW, renderItem.resH);
|
||||
|
||||
GetIEditor()->GetMovieSystem()->EnableFixedStepForCapture(m_renderContext.captureOptions.timeStep);
|
||||
|
||||
// The capturing doesn't actually start here. It just flags the warming-up and
|
||||
@@ -1205,7 +1206,7 @@ void CSequenceBatchRenderDialog::OnUpdateFinalize()
|
||||
m_renderContext.frameNumber = 0;
|
||||
m_renderContext.capturingFrame = false;
|
||||
|
||||
AZ::Render::FrameCaptureNotificationBus::Handler::BusDisconnect();
|
||||
m_atomOutputFrameCapture.DestroyPipeline(*TrackView::SceneFromGameEntityContext());
|
||||
|
||||
// Check to see if there is more items to process
|
||||
bool done = m_renderContext.currentItemIndex == m_renderItems.size() - 1;
|
||||
@@ -1330,6 +1331,9 @@ void CSequenceBatchRenderDialog::OnKickIdle()
|
||||
// being captured, it's safe to move to the next step of the main update
|
||||
if (!capturing() || !m_renderContext.capturingFrame)
|
||||
{
|
||||
const auto& renderItem = m_renderItems[m_renderContext.currentItemIndex];
|
||||
// update the view given the current camera transform and projection
|
||||
UpdateAtomOutputFrameCaptureView(m_atomOutputFrameCapture, renderItem.resW, renderItem.resH);
|
||||
GetIEditor()->GetGameEngine()->Update(); // step update (original frame capture)
|
||||
}
|
||||
|
||||
@@ -1341,14 +1345,24 @@ void CSequenceBatchRenderDialog::OnKickIdle()
|
||||
m_renderContext.captureOptions.folder.c_str(), fileName.c_str(), filePath, /*caseInsensitive=*/true,
|
||||
/*normalize=*/false);
|
||||
|
||||
bool capturedScreenshot = false;
|
||||
AZ::Render::FrameCaptureRequestBus::BroadcastResult(
|
||||
capturedScreenshot, &AZ::Render::FrameCaptureRequestBus::Events::CaptureScreenshot, filePath);
|
||||
// track view callback after each frame is captured
|
||||
const auto captureFinishedCallback = [this]() {
|
||||
m_renderContext.capturingFrame = false;
|
||||
GetIEditor()->GetMovieSystem()->EndCapture();
|
||||
GetIEditor()->GetMovieSystem()->ControlCapture();
|
||||
};
|
||||
|
||||
if (capturedScreenshot)
|
||||
{
|
||||
m_renderContext.capturingFrame = true;
|
||||
}
|
||||
// readback result callback (how the image should be captured)
|
||||
// currently only .dds
|
||||
const auto readbackCallback = [filePath](const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult) {
|
||||
if (const AZ::Render::FrameCaptureOutputResult result = AZ::Render::DdsFrameCaptureOutput(filePath, readbackResult);
|
||||
result.m_errorMessage.has_value())
|
||||
{
|
||||
AZ_Printf("TrackView", "Frame capture failed: %s", result.m_errorMessage.value().c_str());
|
||||
}
|
||||
};
|
||||
|
||||
m_renderContext.capturingFrame = m_atomOutputFrameCapture.BeginCapture(readbackCallback, captureFinishedCallback);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1358,14 +1372,6 @@ void CSequenceBatchRenderDialog::OnKickIdle()
|
||||
}
|
||||
}
|
||||
|
||||
void CSequenceBatchRenderDialog::OnCaptureFinished(
|
||||
[[maybe_unused]] AZ::Render::FrameCaptureResult result, [[maybe_unused]] const AZStd::string& info)
|
||||
{
|
||||
m_renderContext.capturingFrame = false;
|
||||
GetIEditor()->GetMovieSystem()->EndCapture();
|
||||
GetIEditor()->GetMovieSystem()->ControlCapture();
|
||||
}
|
||||
|
||||
void CSequenceBatchRenderDialog::OnCancelRender()
|
||||
{
|
||||
if (m_renderContext.captureState == CaptureState::Capturing)
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AtomOutputFrameCapture.h"
|
||||
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <Atom/Feature/Utils/FrameCaptureBus.h>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QTimer>
|
||||
@@ -33,7 +34,6 @@ namespace Ui
|
||||
class CSequenceBatchRenderDialog
|
||||
: public QDialog
|
||||
, public IMovieListener
|
||||
, private AZ::Render::FrameCaptureNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
CSequenceBatchRenderDialog(float fps, QWidget* pParent = nullptr);
|
||||
@@ -219,9 +219,6 @@ protected slots:
|
||||
bool GetResolutionFromCustomResText(const char* customResText, int& retCustomWidth, int& retCustomHeight) const;
|
||||
|
||||
private:
|
||||
// FrameCaptureNotificationBus overrides ...
|
||||
void OnCaptureFinished(AZ::Render::FrameCaptureResult result, const AZStd::string& info) override;
|
||||
|
||||
void CheckForEnableUpdateButton();
|
||||
void stashActiveViewportResolution();
|
||||
void UpdateSpinnerProgressMessage(const char* description);
|
||||
@@ -234,4 +231,6 @@ private:
|
||||
bool m_editorIdleProcessingEnabled;
|
||||
int32 CV_TrackViewRenderOutputCapturing;
|
||||
QScopedPointer<CPrefixValidator> m_prefixValidator;
|
||||
|
||||
TrackView::AtomOutputFrameCapture m_atomOutputFrameCapture;
|
||||
};
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
// AzCore
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
|
||||
// AzFramework
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
@@ -751,10 +752,13 @@ bool CFileUtil::ScanDirectory(const QString& path, const QString& file, IFileUti
|
||||
|
||||
void CFileUtil::ShowInExplorer([[maybe_unused]] const QString& path)
|
||||
{
|
||||
const char* assetRoot;
|
||||
EBUS_EVENT_RESULT(assetRoot, AzFramework::ApplicationRequests::Bus, GetAssetRoot);
|
||||
AZStd::string assetRoot;
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
settingsRegistry->Get(assetRoot, AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder);
|
||||
}
|
||||
|
||||
QString fullpath(assetRoot);
|
||||
auto fullpath = QString::fromUtf8(assetRoot.c_str(), aznumeric_cast<int>(assetRoot.size()));
|
||||
AzQtComponents::ShowFileOnDesktop(fullpath);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <QDesktopWidget>
|
||||
#include <QTimer>
|
||||
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
// AzFramework
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
|
||||
@@ -93,7 +95,8 @@ WelcomeScreenDialog::WelcomeScreenDialog(QWidget* pParent)
|
||||
auto currentProjectButtonMenu = new QMenu();
|
||||
|
||||
ui->currentProjectButton->setMenu(currentProjectButtonMenu);
|
||||
ui->currentProjectButton->setText(gEnv->pConsole->GetCVar("sys_game_folder")->GetString());
|
||||
auto projectName = AZ::Utils::GetProjectName();
|
||||
ui->currentProjectButton->setText(projectName.c_str());
|
||||
ui->currentProjectButton->adjustSize();
|
||||
ui->currentProjectButton->setMinimumWidth(ui->currentProjectButton->width() + 40);
|
||||
|
||||
@@ -193,10 +196,9 @@ void WelcomeScreenDialog::SetRecentFileList(RecentFileList* pList)
|
||||
|
||||
const char* engineRoot;
|
||||
EBUS_EVENT_RESULT(engineRoot, AzFramework::ApplicationRequests::Bus, GetEngineRoot);
|
||||
AZStd::string gamePathString;
|
||||
AZ::StringFunc::Path::Join(engineRoot, gEnv->pConsole->GetCVar("sys_game_folder")->GetString(), gamePathString);
|
||||
|
||||
QString gamePath = QString(gamePathString.c_str());
|
||||
auto projectPath = AZ::Utils::GetProjectPath();
|
||||
QString gamePath{projectPath.c_str()};
|
||||
Path::ConvertSlashToBackSlash(gamePath);
|
||||
gamePath = Path::ToUnixPath(gamePath.toLower());
|
||||
gamePath = Path::AddSlash(gamePath);
|
||||
|
||||
@@ -807,6 +807,8 @@ set(FILES
|
||||
EnvironmentPanel.cpp
|
||||
EnvironmentPanel.h
|
||||
EnvironmentPanel.ui
|
||||
TrackView/AtomOutputFrameCapture.cpp
|
||||
TrackView/AtomOutputFrameCapture.h
|
||||
TrackView/TrackViewDialog.qrc
|
||||
TrackView/TrackViewDialog.cpp
|
||||
TrackView/TrackViewDialog.h
|
||||
|
||||
Reference in New Issue
Block a user