Integrating up through commit 90f050496
This commit is contained in:
@@ -191,6 +191,8 @@ void LevelEditorMenuHandler::Initialize()
|
||||
m_viewPaneManager, &QtViewPaneManager::registeredPanesChanged,
|
||||
this, &LevelEditorMenuHandler::ResetToolsMenus);
|
||||
|
||||
m_levelExtension = EditorUtils::LevelFile::GetDefaultFileExtension();
|
||||
|
||||
m_topLevelMenus << CreateFileMenu();
|
||||
|
||||
auto editMenu = CreateEditMenu();
|
||||
@@ -230,6 +232,11 @@ bool LevelEditorMenuHandler::MRUEntryIsValid(const QString& entry, const QString
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!entry.endsWith(m_levelExtension))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const QDir gameDir(gameFolderPath);
|
||||
QDir dir(entry); // actually pointing at file, first cdUp() gets us the parent dir
|
||||
while (dir.cdUp())
|
||||
@@ -473,8 +480,18 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe
|
||||
// editMenu->addAction(ID_EDIT_PASTE);
|
||||
// editMenu.AddSeparator();
|
||||
|
||||
// Duplicate
|
||||
editMenu.AddAction(ID_EDIT_CLONE);
|
||||
bool isPrefabSystemEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(isPrefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
bool prefabWipFeaturesEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
prefabWipFeaturesEnabled, &AzFramework::ApplicationRequests::ArePrefabWipFeaturesEnabled);
|
||||
|
||||
if (!isPrefabSystemEnabled || (isPrefabSystemEnabled && prefabWipFeaturesEnabled))
|
||||
{
|
||||
// Duplicate
|
||||
editMenu.AddAction(ID_EDIT_CLONE);
|
||||
}
|
||||
|
||||
// Delete
|
||||
editMenu.AddAction(ID_EDIT_DELETE);
|
||||
@@ -701,8 +718,15 @@ QMenu* LevelEditorMenuHandler::CreateGameMenu()
|
||||
gameMenu.AddAction(ID_SWITCH_PHYSICS);
|
||||
gameMenu.AddSeparator();
|
||||
|
||||
// Export to Engine
|
||||
gameMenu.AddAction(ID_FILE_EXPORTTOGAMENOSURFACETEXTURE);
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
if (!usePrefabSystemForLevels)
|
||||
{
|
||||
// Export to Engine
|
||||
gameMenu.AddAction(ID_FILE_EXPORTTOGAMENOSURFACETEXTURE);
|
||||
}
|
||||
|
||||
// Export Selected Objects
|
||||
gameMenu.AddAction(ID_FILE_EXPORT_SELECTEDOBJECTS);
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
|
||||
void Initialize();
|
||||
|
||||
static bool MRUEntryIsValid(const QString& entry, const QString& gameFolderPath);
|
||||
bool MRUEntryIsValid(const QString& entry, const QString& gameFolderPath);
|
||||
|
||||
void IncrementViewPaneVersion();
|
||||
int GetViewPaneVersion() const;
|
||||
@@ -119,6 +119,7 @@ private:
|
||||
ActionManager::MenuWrapper m_layoutsMenu;
|
||||
ActionManager::MenuWrapper m_macrosMenu;
|
||||
|
||||
const char* m_levelExtension = nullptr;
|
||||
int m_viewPaneVersion = 0;
|
||||
|
||||
QList<QMenu*> m_topLevelMenus;
|
||||
|
||||
@@ -187,24 +187,11 @@ AZ_POP_DISABLE_WARNING
|
||||
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
|
||||
static const char defaultFileExtension[] = ".ly";
|
||||
static const char oldFileExtension[] = ".cry";
|
||||
|
||||
static const char lumberyardEditorClassName[] = "LumberyardEditorClass";
|
||||
static const char lumberyardApplicationName[] = "LumberyardApplication";
|
||||
|
||||
static AZ::EnvironmentVariable<bool> inEditorBatchMode = nullptr;
|
||||
|
||||
const char* GetCryEditDefaultFileExtension()
|
||||
{
|
||||
return defaultFileExtension;
|
||||
}
|
||||
|
||||
const char* GetCryEditOldFileExtension()
|
||||
{
|
||||
return oldFileExtension;
|
||||
}
|
||||
|
||||
RecentFileList::RecentFileList()
|
||||
{
|
||||
m_settings.beginGroup(QStringLiteral("Application"));
|
||||
@@ -985,8 +972,9 @@ CCrySingleDocTemplate::Confidence CCrySingleDocTemplate::MatchDocType(LPCTSTR lp
|
||||
}
|
||||
|
||||
// see if it matches our default suffix
|
||||
const QString strFilterExt = GetCryEditDefaultFileExtension();
|
||||
const QString strOldFilterExt = GetCryEditOldFileExtension();
|
||||
|
||||
const QString strFilterExt = EditorUtils::LevelFile::GetDefaultFileExtension();
|
||||
const QString strOldFilterExt = EditorUtils::LevelFile::GetOldCryFileExtension();
|
||||
const QString strSliceFilterExt = AzToolsFramework::SliceUtilities::GetSliceFileExtension().c_str();
|
||||
|
||||
// see if extension matches
|
||||
@@ -1267,6 +1255,9 @@ void CCryEditApp::InitPlugins()
|
||||
// aren't set up yet. If in doubt, wrap it in a QTimer::singleShot(0ms);
|
||||
void CCryEditApp::InitLevel(const CEditCommandLineInfo& cmdInfo)
|
||||
{
|
||||
const char* defaultExtension = EditorUtils::LevelFile::GetDefaultFileExtension();
|
||||
const char* oldExtension = EditorUtils::LevelFile::GetOldCryFileExtension();
|
||||
|
||||
if (m_bPreviewMode)
|
||||
{
|
||||
GetIEditor()->EnableAcceleratos(false);
|
||||
@@ -1295,7 +1286,8 @@ void CCryEditApp::InitLevel(const CEditCommandLineInfo& cmdInfo)
|
||||
QTimer::singleShot(0, QCoreApplication::instance(), &QCoreApplication::quit);
|
||||
return;
|
||||
}
|
||||
else if ((cmdInfo.m_strFileName.endsWith(GetCryEditDefaultFileExtension(), Qt::CaseInsensitive)) || (cmdInfo.m_strFileName.endsWith(GetCryEditOldFileExtension(), Qt::CaseInsensitive)))
|
||||
else if ((cmdInfo.m_strFileName.endsWith(defaultExtension, Qt::CaseInsensitive))
|
||||
|| (cmdInfo.m_strFileName.endsWith(oldExtension, Qt::CaseInsensitive)))
|
||||
{
|
||||
auto pDocument = OpenDocumentFile(cmdInfo.m_strFileName.toUtf8().constData());
|
||||
if (pDocument)
|
||||
@@ -2328,7 +2320,7 @@ int CCryEditApp::ExitInstance(int exitCode)
|
||||
// if we're aborting due to an unexpected shutdown then don't call into objects that don't exist yet.
|
||||
if ((gEnv) && (gEnv->pSystem) && (gEnv->pSystem->GetILevelSystem()))
|
||||
{
|
||||
gEnv->pSystem->GetILevelSystem()->UnLoadLevel();
|
||||
gEnv->pSystem->GetILevelSystem()->UnloadLevel();
|
||||
}
|
||||
|
||||
if (GetIEditor())
|
||||
@@ -2574,6 +2566,15 @@ void CCryEditApp::DisplayLevelLoadErrors()
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::ExportLevel(bool bExportToGame, bool bExportTexture, bool bAutoExport)
|
||||
{
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
if (usePrefabSystemForLevels)
|
||||
{
|
||||
AZ_Assert(false, "Prefab system doesn't require level exports.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (bExportTexture)
|
||||
{
|
||||
CGameExporter gameExporter;
|
||||
@@ -2606,6 +2607,15 @@ void CCryEditApp::OnEditFetch()
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CCryEditApp::UserExportToGame(bool bNoMsgBox)
|
||||
{
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
if (usePrefabSystemForLevels)
|
||||
{
|
||||
AZ_Assert(false, "Export Level should no longer exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GetIEditor()->GetGameEngine()->IsLevelLoaded())
|
||||
{
|
||||
if (bNoMsgBox == false)
|
||||
@@ -2645,6 +2655,15 @@ bool CCryEditApp::UserExportToGame(bool bNoMsgBox)
|
||||
|
||||
void CCryEditApp::ExportToGame(bool bNoMsgBox)
|
||||
{
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
if (usePrefabSystemForLevels)
|
||||
{
|
||||
AZ_Assert(false, "Prefab system no longer exports levels.");
|
||||
return;
|
||||
}
|
||||
|
||||
CGameEngine* pGameEngine = GetIEditor()->GetGameEngine();
|
||||
if (!pGameEngine->IsLevelLoaded())
|
||||
{
|
||||
@@ -3982,6 +4001,10 @@ void CCryEditApp::OnUpdatePlayGame(QAction* action)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CCryEditApp::ECreateLevelResult CCryEditApp::CreateLevel(const QString& levelName, QString& fullyQualifiedLevelName /* ={} */)
|
||||
{
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
|
||||
// If we are creating a new level and we're in simulate mode, then switch it off before we do anything else
|
||||
if (GetIEditor()->GetGameEngine() && GetIEditor()->GetGameEngine()->GetSimulationMode())
|
||||
{
|
||||
@@ -4004,7 +4027,7 @@ CCryEditApp::ECreateLevelResult CCryEditApp::CreateLevel(const QString& levelNam
|
||||
|
||||
QString cryFileName = levelName.mid(levelName.lastIndexOf('/') + 1, levelName.length() - levelName.lastIndexOf('/') + 1);
|
||||
QString levelPath = QStringLiteral("%1/Levels/%2/").arg(Path::GetEditingGameDataFolder().c_str(), levelName);
|
||||
fullyQualifiedLevelName = levelPath + cryFileName + GetCryEditDefaultFileExtension();
|
||||
fullyQualifiedLevelName = levelPath + cryFileName + EditorUtils::LevelFile::GetDefaultFileExtension();
|
||||
|
||||
//_MAX_PATH includes null terminator, so we actually want to cap at _MAX_PATH-1
|
||||
if (fullyQualifiedLevelName.length() >= _MAX_PATH-1)
|
||||
@@ -4050,10 +4073,13 @@ CCryEditApp::ECreateLevelResult CCryEditApp::CreateLevel(const QString& levelNam
|
||||
|
||||
if (GetIEditor()->GetDocument()->Save())
|
||||
{
|
||||
m_bIsExportingLegacyData = true;
|
||||
CGameExporter gameExporter;
|
||||
gameExporter.Export();
|
||||
m_bIsExportingLegacyData = false;
|
||||
if (!usePrefabSystemForLevels)
|
||||
{
|
||||
m_bIsExportingLegacyData = true;
|
||||
CGameExporter gameExporter;
|
||||
gameExporter.Export();
|
||||
m_bIsExportingLegacyData = false;
|
||||
}
|
||||
|
||||
GetIEditor()->GetGameEngine()->LoadLevel(GetIEditor()->GetGameEngine()->GetMissionName(), true, true);
|
||||
GetIEditor()->GetSystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_PRECACHE_START, 0, 0);
|
||||
@@ -4062,6 +4088,7 @@ CCryEditApp::ECreateLevelResult CCryEditApp::CreateLevel(const QString& levelNam
|
||||
GetIEditor()->GetSystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_PRECACHE_END, 0, 0);
|
||||
}
|
||||
|
||||
if (!usePrefabSystemForLevels)
|
||||
{
|
||||
// No terrain, but still need to export default octree and visarea data.
|
||||
CGameExporter gameExporter;
|
||||
@@ -5412,8 +5439,8 @@ void CCryEditApp::StartProcessDetached(const char* process, const char* args)
|
||||
|
||||
// separate the string based on spaces for paths like "-launch", "lua", "-files";
|
||||
// also separate the string and keep spaces inside the folder path;
|
||||
// Ex: C:\dev\Foundation\dev\Cache\SamplesProject\pc\samplesproject\scripts\components\a a\empty.lua;
|
||||
// Ex: C:\dev\Foundation\dev\Cache\SamplesProject\pc\samplesproject\scripts\components\a a\'empty'.lua;
|
||||
// Ex: C:\dev\Foundation\dev\Cache\AutomatedTesting\pc\automatedtesting\scripts\components\a a\empty.lua;
|
||||
// Ex: C:\dev\Foundation\dev\Cache\AutomatedTesting\pc\automatedtesting\scripts\components\a a\'empty'.lua;
|
||||
AZStd::string currentStr(args);
|
||||
AZStd::size_t firstQuotePos = AZStd::string::npos;
|
||||
AZStd::size_t secondQuotePos = 0;
|
||||
|
||||
+312
-175
@@ -22,9 +22,11 @@
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
// AzFramework
|
||||
#include <AzFramework/Archive/IArchive.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzFramework/API/AtomActiveInterface.h>
|
||||
|
||||
// AzToolsFramework
|
||||
@@ -32,6 +34,7 @@
|
||||
#include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
|
||||
#include <AzToolsFramework/UI/Layer/NameConflictWarning.hxx>
|
||||
#include <AzToolsFramework/API/EditorLevelNotificationBus.h>
|
||||
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
|
||||
|
||||
// CryCommon
|
||||
#include <CryCommon/IAudioSystem.h>
|
||||
@@ -147,7 +150,6 @@ CCryEditDoc::CCryEditDoc()
|
||||
m_bDocumentReady = false;
|
||||
GetIEditor()->SetDocument(this);
|
||||
CLogFile::WriteLine("Document created");
|
||||
m_pTmpXmlArchHack = 0;
|
||||
RegisterConsoleVariables();
|
||||
|
||||
MainWindow::instance()->GetActionManager()->RegisterActionHandler(ID_FILE_SAVE_AS, this, &CCryEditDoc::OnFileSaveAs);
|
||||
@@ -336,35 +338,39 @@ void CCryEditDoc::Save(CXmlArchive& xmlAr)
|
||||
|
||||
void CCryEditDoc::Save(TDocMultiArchive& arrXmlAr)
|
||||
{
|
||||
m_pTmpXmlArchHack = arrXmlAr[DMAS_GENERAL];
|
||||
CAutoDocNotReady autoDocNotReady;
|
||||
QString currentMissionName;
|
||||
bool isPrefabEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(isPrefabEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
if (arrXmlAr[DMAS_GENERAL] != NULL)
|
||||
if (!isPrefabEnabled)
|
||||
{
|
||||
(*arrXmlAr[DMAS_GENERAL]).root = XmlHelpers::CreateXmlNode("Level");
|
||||
(*arrXmlAr[DMAS_GENERAL]).root->setAttr("WaterColor", m_waterColor);
|
||||
CAutoDocNotReady autoDocNotReady;
|
||||
QString currentMissionName;
|
||||
|
||||
char version[50];
|
||||
GetIEditor()->GetFileVersion().ToString(version, AZ_ARRAY_SIZE(version));
|
||||
(*arrXmlAr[DMAS_GENERAL]).root->setAttr("SandboxVersion", version);
|
||||
if (arrXmlAr[DMAS_GENERAL] != NULL)
|
||||
{
|
||||
(*arrXmlAr[DMAS_GENERAL]).root = XmlHelpers::CreateXmlNode("Level");
|
||||
(*arrXmlAr[DMAS_GENERAL]).root->setAttr("WaterColor", m_waterColor);
|
||||
|
||||
SerializeViewSettings((*arrXmlAr[DMAS_GENERAL]));
|
||||
char version[50];
|
||||
GetIEditor()->GetFileVersion().ToString(version, AZ_ARRAY_SIZE(version));
|
||||
(*arrXmlAr[DMAS_GENERAL]).root->setAttr("SandboxVersion", version);
|
||||
|
||||
// Fog settings ///////////////////////////////////////////////////////
|
||||
SerializeFogSettings((*arrXmlAr[DMAS_GENERAL]));
|
||||
// Serialize Missions //////////////////////////////////////////////////
|
||||
SerializeMissions(arrXmlAr, currentMissionName, false);
|
||||
//! Serialize material manager.
|
||||
GetIEditor()->GetMaterialManager()->Serialize((*arrXmlAr[DMAS_GENERAL]).root, (*arrXmlAr[DMAS_GENERAL]).bLoading);
|
||||
//! Serialize LensFlare manager.
|
||||
GetIEditor()->GetLensFlareManager()->Serialize((*arrXmlAr[DMAS_GENERAL]).root, (*arrXmlAr[DMAS_GENERAL]).bLoading);
|
||||
SerializeViewSettings((*arrXmlAr[DMAS_GENERAL]));
|
||||
|
||||
SerializeShaderCache((*arrXmlAr[DMAS_GENERAL_NAMED_DATA]));
|
||||
SerializeNameSelection((*arrXmlAr[DMAS_GENERAL]));
|
||||
// Fog settings ///////////////////////////////////////////////////////
|
||||
SerializeFogSettings((*arrXmlAr[DMAS_GENERAL]));
|
||||
// Serialize Missions //////////////////////////////////////////////////
|
||||
SerializeMissions(arrXmlAr, currentMissionName, false);
|
||||
//! Serialize material manager.
|
||||
GetIEditor()->GetMaterialManager()->Serialize((*arrXmlAr[DMAS_GENERAL]).root, (*arrXmlAr[DMAS_GENERAL]).bLoading);
|
||||
//! Serialize LensFlare manager.
|
||||
GetIEditor()->GetLensFlareManager()->Serialize((*arrXmlAr[DMAS_GENERAL]).root, (*arrXmlAr[DMAS_GENERAL]).bLoading);
|
||||
|
||||
SerializeShaderCache((*arrXmlAr[DMAS_GENERAL_NAMED_DATA]));
|
||||
SerializeNameSelection((*arrXmlAr[DMAS_GENERAL]));
|
||||
}
|
||||
}
|
||||
AfterSave();
|
||||
m_pTmpXmlArchHack = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -378,18 +384,28 @@ void CCryEditDoc::Load(CXmlArchive& xmlAr, const QString& szFilename)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
|
||||
{
|
||||
bool isPrefabEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(isPrefabEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
m_hasErrors = false;
|
||||
|
||||
// Register a unique load event
|
||||
QString fileName = Path::GetFileName(szFilename);
|
||||
QString levelHash = GetIEditor()->GetSettingsManager()->GenerateContentHash(arrXmlAr[DMAS_GENERAL]->root, fileName);
|
||||
QString levelHash;
|
||||
if (!isPrefabEnabled)
|
||||
{
|
||||
levelHash = GetIEditor()->GetSettingsManager()->GenerateContentHash(arrXmlAr[DMAS_GENERAL]->root, fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
levelHash = szFilename;
|
||||
}
|
||||
SEventLog loadEvent("Level_" + Path::GetFileName(fileName), "", levelHash);
|
||||
|
||||
// Register this level and its content hash as version
|
||||
GetIEditor()->GetSettingsManager()->AddToolVersion(fileName, levelHash);
|
||||
GetIEditor()->GetSettingsManager()->RegisterEvent(loadEvent);
|
||||
LOADING_TIME_PROFILE_SECTION(gEnv->pSystem);
|
||||
m_pTmpXmlArchHack = arrXmlAr[DMAS_GENERAL];
|
||||
CAutoDocNotReady autoDocNotReady;
|
||||
|
||||
HEAP_CHECK
|
||||
@@ -421,13 +437,23 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
|
||||
// Start recording errors
|
||||
const ICVar* pShowErrorDialogOnLoad = gEnv->pConsole->GetCVar("ed_showErrorDialogOnLoad");
|
||||
CErrorsRecorder errorsRecorder(pShowErrorDialogOnLoad && (pShowErrorDialogOnLoad->GetIVal() != 0));
|
||||
AZStd::string levelPakPath;
|
||||
if (AzFramework::StringFunc::Path::ConstructFull(szLevelPath.toUtf8().data(), "level", "pak", levelPakPath, true))
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
|
||||
if (!usePrefabSystemForLevels)
|
||||
{
|
||||
//Check whether level.pak is present
|
||||
if (!gEnv->pFileIO->Exists(levelPakPath.c_str()))
|
||||
AZStd::string levelPakPath;
|
||||
if (AzFramework::StringFunc::Path::ConstructFull(szLevelPath.toUtf8().data(), "level", "pak", levelPakPath, true))
|
||||
{
|
||||
CryWarning(VALIDATOR_MODULE_EDITOR, VALIDATOR_WARNING, "level.pak is missing. This will cause other errors. To fix this, re-export the level.");
|
||||
// Check whether level.pak is present
|
||||
if (!gEnv->pFileIO->Exists(levelPakPath.c_str()))
|
||||
{
|
||||
CryWarning(
|
||||
VALIDATOR_MODULE_EDITOR, VALIDATOR_WARNING,
|
||||
"level.pak is missing. This will cause other errors. To fix this, re-export the level.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,16 +491,20 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
|
||||
|
||||
HEAP_CHECK
|
||||
|
||||
// multiple missions are no longer supported, only load the current mission (last used)
|
||||
SerializeMissions(arrXmlAr, currentMissionName, false);
|
||||
if (!isPrefabEnabled)
|
||||
{
|
||||
// multiple missions are no longer supported, only load the current mission (last used)
|
||||
SerializeMissions(arrXmlAr, currentMissionName, false);
|
||||
}
|
||||
|
||||
HEAP_CHECK
|
||||
|
||||
if (GetIEditor()->Get3DEngine())
|
||||
{
|
||||
CAutoLogTime logtime("Load Terrain");
|
||||
bool terrainLoaded = GetIEditor()->Get3DEngine()->LoadCompiledOctreeForEditor();
|
||||
AZ_Assert(terrainLoaded, "Failed to load Terrain data file.");
|
||||
if (!isPrefabEnabled)
|
||||
{
|
||||
GetIEditor()->Get3DEngine()->LoadCompiledOctreeForEditor();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
@@ -482,37 +512,40 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
|
||||
GetIEditor()->GetGameEngine()->LoadLevel(currentMissionName, true, true);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Load water color.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
(*arrXmlAr[DMAS_GENERAL]).root->getAttr("WaterColor", m_waterColor);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Load materials.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (!isPrefabEnabled)
|
||||
{
|
||||
CAutoLogTime logtime("Load MaterialManager");
|
||||
GetIEditor()->GetMaterialManager()->Serialize((*arrXmlAr[DMAS_GENERAL]).root, (*arrXmlAr[DMAS_GENERAL]).bLoading);
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Load water color.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
(*arrXmlAr[DMAS_GENERAL]).root->getAttr("WaterColor", m_waterColor);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Load materials.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
{
|
||||
CAutoLogTime logtime("Load MaterialManager");
|
||||
GetIEditor()->GetMaterialManager()->Serialize((*arrXmlAr[DMAS_GENERAL]).root, (*arrXmlAr[DMAS_GENERAL]).bLoading);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Load LensFlares.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
{
|
||||
CAutoLogTime logtime("Load Flares");
|
||||
GetIEditor()->GetLensFlareManager()->Serialize((*arrXmlAr[DMAS_GENERAL]).root, (*arrXmlAr[DMAS_GENERAL]).bLoading);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Load View Settings
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SerializeViewSettings((*arrXmlAr[DMAS_GENERAL]));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Fog settings
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SerializeFogSettings((*arrXmlAr[DMAS_GENERAL]));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Load LensFlares.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
{
|
||||
CAutoLogTime logtime("Load Flares");
|
||||
GetIEditor()->GetLensFlareManager()->Serialize((*arrXmlAr[DMAS_GENERAL]).root, (*arrXmlAr[DMAS_GENERAL]).bLoading);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Load View Settings
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SerializeViewSettings((*arrXmlAr[DMAS_GENERAL]));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Fog settings
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SerializeFogSettings((*arrXmlAr[DMAS_GENERAL]));
|
||||
|
||||
{
|
||||
QByteArray str;
|
||||
str = tr("Activating Mission %1").arg(currentMissionName).toUtf8();
|
||||
@@ -534,8 +567,9 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
|
||||
|
||||
ForceSkyUpdate();
|
||||
|
||||
// Serialize Shader Cache.
|
||||
if (!isPrefabEnabled)
|
||||
{
|
||||
// Serialize Shader Cache.
|
||||
CAutoLogTime logtime("Load Level Shader Cache");
|
||||
SerializeShaderCache((*arrXmlAr[DMAS_GENERAL_NAMED_DATA]));
|
||||
}
|
||||
@@ -560,8 +594,11 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
|
||||
}
|
||||
}
|
||||
|
||||
// Name Selection groups
|
||||
SerializeNameSelection((*arrXmlAr[DMAS_GENERAL]));
|
||||
if (!isPrefabEnabled)
|
||||
{
|
||||
// Name Selection groups
|
||||
SerializeNameSelection((*arrXmlAr[DMAS_GENERAL]));
|
||||
}
|
||||
|
||||
{
|
||||
CAutoLogTime logtime("Post Load");
|
||||
@@ -580,7 +617,6 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
|
||||
#endif
|
||||
|
||||
LogLoadTime(GetTickCount() - t0);
|
||||
m_pTmpXmlArchHack = 0;
|
||||
// Loaded with success, remove event from log file
|
||||
GetIEditor()->GetSettingsManager()->UnregisterEvent(loadEvent);
|
||||
}
|
||||
@@ -943,10 +979,18 @@ bool CCryEditDoc::OnOpenDocument(const QString& lpszPathName)
|
||||
bool CCryEditDoc::BeforeOpenDocument(const QString& lpszPathName, TOpenDocContext& context)
|
||||
{
|
||||
CTimeValue loading_start_time = gEnv->pTimer->GetAsyncTime();
|
||||
//ensure we close any open packs
|
||||
if (!GetIEditor()->GetLevelFolder().isEmpty())
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
|
||||
if (!usePrefabSystemForLevels)
|
||||
{
|
||||
GetIEditor()->GetSystem()->GetIPak()->ClosePack((GetIEditor()->GetLevelFolder() + "\\level.pak").toUtf8().data());
|
||||
// ensure we close any open packs
|
||||
if (!GetIEditor()->GetLevelFolder().isEmpty())
|
||||
{
|
||||
GetIEditor()->GetSystem()->GetIPak()->ClosePack((GetIEditor()->GetLevelFolder() + "\\level.pak").toUtf8().data());
|
||||
}
|
||||
}
|
||||
|
||||
// restore directory to root.
|
||||
@@ -977,6 +1021,9 @@ bool CCryEditDoc::DoOpenDocument(TOpenDocContext& context)
|
||||
{
|
||||
CTimeValue& loading_start_time = context.loading_start_time;
|
||||
|
||||
bool isPrefabEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(isPrefabEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
// normalize the path so that its the same in all following calls:
|
||||
QString levelFilePath = QFileInfo(context.absoluteLevelPath).absoluteFilePath();
|
||||
context.absoluteLevelPath = levelFilePath;
|
||||
@@ -985,20 +1032,28 @@ bool CCryEditDoc::DoOpenDocument(TOpenDocContext& context)
|
||||
|
||||
auto pIPak = GetIEditor()->GetSystem()->GetIPak();
|
||||
|
||||
// if the level pack exists, open that, too:
|
||||
QString levelFolderAbsolutePath = QFileInfo(context.absoluteLevelPath).absolutePath();
|
||||
QString levelPackFileAbsolutePath = QDir(levelFolderAbsolutePath).absoluteFilePath("level.pak");
|
||||
|
||||
// we mount the pack (level.pak) using the folder its sitting in as the mountpoint (first parameter)
|
||||
pIPak->OpenPack(levelFolderAbsolutePath.toUtf8().constData(), levelPackFileAbsolutePath.toUtf8().constData());
|
||||
|
||||
TDocMultiArchive arrXmlAr = {};
|
||||
if (!LoadXmlArchiveArray(arrXmlAr, levelFilePath, levelFolderAbsolutePath))
|
||||
if (!isPrefabEnabled)
|
||||
{
|
||||
m_bLoadFailed = true;
|
||||
return FALSE;
|
||||
// if the level pack exists, open that, too:
|
||||
QString levelPackFileAbsolutePath = QDir(levelFolderAbsolutePath).absoluteFilePath("level.pak");
|
||||
|
||||
// we mount the pack (level.pak) using the folder its sitting in as the mountpoint (first parameter)
|
||||
pIPak->OpenPack(levelFolderAbsolutePath.toUtf8().constData(), levelPackFileAbsolutePath.toUtf8().constData());
|
||||
}
|
||||
|
||||
TDocMultiArchive arrXmlAr = {};
|
||||
|
||||
if (!isPrefabEnabled)
|
||||
{
|
||||
if (!LoadXmlArchiveArray(arrXmlAr, levelFilePath, levelFolderAbsolutePath))
|
||||
{
|
||||
m_bLoadFailed = true;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (!LoadLevel(arrXmlAr, context.absoluteLevelPath))
|
||||
{
|
||||
m_bLoadFailed = true;
|
||||
@@ -1273,6 +1328,7 @@ bool CCryEditDoc::SaveLevel(const QString& filename)
|
||||
CAutoCheckOutDialogEnableForAll enableForAll;
|
||||
|
||||
QString fullPathName = Path::ToUnixPath(filename);
|
||||
QString originaLevelFilename = Path::GetFile(m_pathName);
|
||||
if (QFileInfo(filename).isRelative())
|
||||
{
|
||||
// Resolving the path through resolvepath would normalize and lowcase it, and in this case, we don't want that.
|
||||
@@ -1331,7 +1387,9 @@ bool CCryEditDoc::SaveLevel(const QString& filename)
|
||||
continue;
|
||||
}
|
||||
|
||||
bool skipFile = sourceName.endsWith(".cry", Qt::CaseInsensitive) || sourceName.endsWith(".ly", Qt::CaseInsensitive); // level file will be written out by saving, ignore the source one
|
||||
bool skipFile = sourceName.endsWith(".cry", Qt::CaseInsensitive) ||
|
||||
sourceName.endsWith(".ly", Qt::CaseInsensitive) ||
|
||||
sourceName == originaLevelFilename; // level file will be written out by saving, ignore the source one
|
||||
if (skipFile)
|
||||
{
|
||||
continue;
|
||||
@@ -1378,81 +1436,112 @@ bool CCryEditDoc::SaveLevel(const QString& filename)
|
||||
QFile(tempSaveFile).setPermissions(QFile::ReadOther | QFile::WriteOther);
|
||||
QFile::remove(tempSaveFile);
|
||||
|
||||
CPakFile pakFile;
|
||||
// Save AZ entities to the editor level.
|
||||
|
||||
bool contentsAllSaved = false; // abort level save if anything within it fails
|
||||
|
||||
auto tempFilenameStrData = tempSaveFile.toStdString();
|
||||
auto filenameStrData = fullPathName.toStdString();
|
||||
|
||||
bool isPrefabEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(isPrefabEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
if (!isPrefabEnabled)
|
||||
{
|
||||
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "CCryEditDoc::SaveLevel Open PakFile");
|
||||
if (!pakFile.Open(tempSaveFile.toUtf8().data(), false))
|
||||
AZStd::vector<char> entitySaveBuffer;
|
||||
bool savedEntities = false;
|
||||
CPakFile pakFile;
|
||||
|
||||
{
|
||||
gEnv->pLog->LogWarning("Unable to open pack file %s for writing", tempSaveFile.toUtf8().data());
|
||||
return false;
|
||||
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "CCryEditDoc::SaveLevel Open PakFile");
|
||||
if (!pakFile.Open(tempSaveFile.toUtf8().data(), false))
|
||||
{
|
||||
gEnv->pLog->LogWarning("Unable to open pack file %s for writing", tempSaveFile.toUtf8().data());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::vector<AZ::Entity*> editorEntities;
|
||||
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
|
||||
&AzToolsFramework::EditorEntityContextRequestBus::Events::GetLooseEditorEntities,
|
||||
editorEntities);
|
||||
|
||||
AZStd::vector<AZ::Entity*> editorEntities;
|
||||
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
|
||||
&AzToolsFramework::EditorEntityContextRequestBus::Events::GetLooseEditorEntities,
|
||||
editorEntities);
|
||||
|
||||
AZStd::vector<AZ::Entity*> layerEntities;
|
||||
AZ::SliceComponent::SliceReferenceToInstancePtrs instancesInLayers;
|
||||
for (AZ::Entity* entity : editorEntities)
|
||||
{
|
||||
AzToolsFramework::Layers::LayerResult layerSaveResult(AzToolsFramework::Layers::LayerResult::CreateSuccess());
|
||||
AzToolsFramework::Layers::EditorLayerComponentRequestBus::EventResult(
|
||||
layerSaveResult,
|
||||
entity->GetId(),
|
||||
&AzToolsFramework::Layers::EditorLayerComponentRequestBus::Events::WriteLayerAndGetEntities,
|
||||
newLevelFolder,
|
||||
layerEntities,
|
||||
instancesInLayers);
|
||||
layerSaveResult.MessageResult();
|
||||
}
|
||||
|
||||
bool pakContentsAllSaved = false; // abort level pak save if anything within it fails
|
||||
|
||||
// Save AZ entities to the editor level pak.
|
||||
bool savedEntities = false;
|
||||
AZStd::vector<char> entitySaveBuffer;
|
||||
AZ::IO::ByteContainerStream<AZStd::vector<char> > entitySaveStream(&entitySaveBuffer);
|
||||
{
|
||||
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "CCryEditDoc::SaveLevel Save Entities To Stream");
|
||||
EBUS_EVENT_RESULT(savedEntities,
|
||||
AzToolsFramework::EditorEntityContextRequestBus,
|
||||
SaveToStreamForEditor, entitySaveStream, layerEntities, instancesInLayers);
|
||||
}
|
||||
|
||||
for (AZ::Entity* entity : editorEntities)
|
||||
{
|
||||
AzToolsFramework::Layers::EditorLayerComponentRequestBus::Event(
|
||||
entity->GetId(),
|
||||
&AzToolsFramework::Layers::EditorLayerComponentRequestBus::Events::RestoreEditorData);
|
||||
}
|
||||
|
||||
if (savedEntities)
|
||||
{
|
||||
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "CCryEditDoc::SaveLevel Updated PakFile levelEntities.editor_xml");
|
||||
pakFile.UpdateFile("LevelEntities.editor_xml", entitySaveBuffer.begin(), entitySaveBuffer.size());
|
||||
|
||||
// Save XML archive to pak file.
|
||||
bool bSaved = xmlAr.SaveToPak(Path::GetPath(tempSaveFile), pakFile);
|
||||
if (bSaved)
|
||||
AZStd::vector<AZ::Entity*> layerEntities;
|
||||
AZ::SliceComponent::SliceReferenceToInstancePtrs instancesInLayers;
|
||||
for (AZ::Entity* entity : editorEntities)
|
||||
{
|
||||
pakContentsAllSaved = true;
|
||||
AzToolsFramework::Layers::LayerResult layerSaveResult(AzToolsFramework::Layers::LayerResult::CreateSuccess());
|
||||
AzToolsFramework::Layers::EditorLayerComponentRequestBus::EventResult(
|
||||
layerSaveResult,
|
||||
entity->GetId(),
|
||||
&AzToolsFramework::Layers::EditorLayerComponentRequestBus::Events::WriteLayerAndGetEntities,
|
||||
newLevelFolder,
|
||||
layerEntities,
|
||||
instancesInLayers);
|
||||
layerSaveResult.MessageResult();
|
||||
}
|
||||
|
||||
AZ::IO::ByteContainerStream<AZStd::vector<char>> entitySaveStream(&entitySaveBuffer);
|
||||
{
|
||||
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "CCryEditDoc::SaveLevel Save Entities To Stream");
|
||||
EBUS_EVENT_RESULT(
|
||||
savedEntities, AzToolsFramework::EditorEntityContextRequestBus, SaveToStreamForEditor, entitySaveStream, layerEntities,
|
||||
instancesInLayers);
|
||||
}
|
||||
|
||||
for (AZ::Entity* entity : editorEntities)
|
||||
{
|
||||
AzToolsFramework::Layers::EditorLayerComponentRequestBus::Event(
|
||||
entity->GetId(), &AzToolsFramework::Layers::EditorLayerComponentRequestBus::Events::RestoreEditorData);
|
||||
}
|
||||
|
||||
if (savedEntities)
|
||||
{
|
||||
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "CCryEditDoc::SaveLevel Updated PakFile levelEntities.editor_xml");
|
||||
pakFile.UpdateFile("LevelEntities.editor_xml", entitySaveBuffer.begin(), entitySaveBuffer.size());
|
||||
|
||||
// Save XML archive to pak file.
|
||||
bool bSaved = xmlAr.SaveToPak(Path::GetPath(tempSaveFile), pakFile);
|
||||
if (bSaved)
|
||||
{
|
||||
contentsAllSaved = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
gEnv->pLog->LogWarning("Unable to write the level data to file %s", tempSaveFile.toUtf8().data());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gEnv->pLog->LogWarning("Unable to write the level data to file %s", tempSaveFile.toUtf8().data());
|
||||
gEnv->pLog->LogWarning("Unable to generate entity data for level save %s", tempSaveFile.toUtf8().data());
|
||||
}
|
||||
|
||||
pakFile.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
gEnv->pLog->LogWarning("Unable to generate entity data for level save %s", tempSaveFile.toUtf8().data());
|
||||
auto prefabEditorEntityOwnershipInterface = AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
|
||||
if (prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
AZ_Assert(fileIO, "No File IO implementation available");
|
||||
|
||||
AZ::IO::HandleType tempSaveFileHandle;
|
||||
AZ::IO::Result openResult = fileIO->Open(tempFilenameStrData.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary, tempSaveFileHandle);
|
||||
contentsAllSaved = openResult;
|
||||
if (openResult)
|
||||
{
|
||||
AZ::IO::FileIOStream stream(tempSaveFileHandle, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary, false);
|
||||
contentsAllSaved = prefabEditorEntityOwnershipInterface->SaveToStream(stream, AZStd::string_view(filenameStrData.data(), filenameStrData.size()));
|
||||
stream.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pakFile.Close();
|
||||
if (!pakContentsAllSaved)
|
||||
if (!contentsAllSaved)
|
||||
{
|
||||
AZ_Error("Editor", false, "Error when writing level '%s' into tmpfile '%s'", filenameStrData.c_str(), tempFilenameStrData.c_str());
|
||||
QFile::remove(tempSaveFile);
|
||||
return false;
|
||||
}
|
||||
@@ -1628,45 +1717,73 @@ bool CCryEditDoc::SaveSlice(const QString& filename)
|
||||
|
||||
bool CCryEditDoc::LoadEntitiesFromLevel(const QString& levelPakFile)
|
||||
{
|
||||
bool isPrefabEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(isPrefabEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
bool loadedSuccessfully = false;
|
||||
|
||||
auto pakSystem = GetIEditor()->GetSystem()->GetIPak();
|
||||
bool pakOpened = pakSystem->OpenPack(levelPakFile.toUtf8().data());
|
||||
if (pakOpened)
|
||||
if (!isPrefabEnabled)
|
||||
{
|
||||
const QString entityFilename = Path::GetPath(levelPakFile) + "LevelEntities.editor_xml";
|
||||
|
||||
CCryFile entitiesFile;
|
||||
if (entitiesFile.Open(entityFilename.toUtf8().data(), "rt"))
|
||||
auto pakSystem = GetIEditor()->GetSystem()->GetIPak();
|
||||
bool pakOpened = pakSystem->OpenPack(levelPakFile.toUtf8().data());
|
||||
if (pakOpened)
|
||||
{
|
||||
AZStd::vector<char> fileBuffer;
|
||||
fileBuffer.resize(entitiesFile.GetLength());
|
||||
if (fileBuffer.size() > 0)
|
||||
{
|
||||
if (fileBuffer.size() == entitiesFile.ReadRaw(fileBuffer.begin(), fileBuffer.size()))
|
||||
{
|
||||
AZ::IO::ByteContainerStream<AZStd::vector<char> > fileStream(&fileBuffer);
|
||||
const QString entityFilename = Path::GetPath(levelPakFile) + "LevelEntities.editor_xml";
|
||||
|
||||
EBUS_EVENT_RESULT(loadedSuccessfully, AzToolsFramework::EditorEntityContextRequestBus, LoadFromStreamWithLayers, fileStream, levelPakFile);
|
||||
CCryFile entitiesFile;
|
||||
if (entitiesFile.Open(entityFilename.toUtf8().data(), "rt"))
|
||||
{
|
||||
AZStd::vector<char> fileBuffer;
|
||||
fileBuffer.resize(entitiesFile.GetLength());
|
||||
if (fileBuffer.size() > 0)
|
||||
{
|
||||
if (fileBuffer.size() == entitiesFile.ReadRaw(fileBuffer.begin(), fileBuffer.size()))
|
||||
{
|
||||
AZ::IO::ByteContainerStream<AZStd::vector<char>> fileStream(&fileBuffer);
|
||||
|
||||
EBUS_EVENT_RESULT(
|
||||
loadedSuccessfully, AzToolsFramework::EditorEntityContextRequestBus, LoadFromStreamWithLayers, fileStream,
|
||||
levelPakFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error(
|
||||
"Editor", false, "Failed to load level entities because the file \"%s\" could not be read.",
|
||||
entityFilename.toUtf8().data());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("Editor", false, "Failed to load level entities because the file \"%s\" could not be read.", entityFilename.toUtf8().data());
|
||||
AZ_Error(
|
||||
"Editor", false, "Failed to load level entities because the file \"%s\" is empty.", entityFilename.toUtf8().data());
|
||||
}
|
||||
|
||||
entitiesFile.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("Editor", false, "Failed to load level entities because the file \"%s\" is empty.", entityFilename.toUtf8().data());
|
||||
AZ_Error(
|
||||
"Editor", false, "Failed to load level entities because the file \"%s\" was not found.",
|
||||
entityFilename.toUtf8().data());
|
||||
}
|
||||
|
||||
entitiesFile.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("Editor", false, "Failed to load level entities because the file \"%s\" was not found.", entityFilename.toUtf8().data());
|
||||
pakSystem->ClosePack(levelPakFile.toUtf8().data());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
AZ_Assert(fileIO, "No File IO implementation available");
|
||||
|
||||
pakSystem->ClosePack(levelPakFile.toUtf8().data());
|
||||
AZ::IO::HandleType fileHandle;
|
||||
AZ::IO::Result openResult = fileIO->Open(levelPakFile.toUtf8().data(), AZ::IO::OpenMode::ModeRead | AZ::IO::OpenMode::ModeBinary, fileHandle);
|
||||
if (openResult)
|
||||
{
|
||||
AZ::IO::FileIOStream stream(fileHandle, AZ::IO::OpenMode::ModeRead | AZ::IO::OpenMode::ModeBinary, false);
|
||||
AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult(
|
||||
loadedSuccessfully, &AzToolsFramework::EditorEntityContextRequests::LoadFromStreamWithLayers, stream, levelPakFile);
|
||||
stream.Close();
|
||||
}
|
||||
}
|
||||
|
||||
return loadedSuccessfully;
|
||||
@@ -1697,14 +1814,21 @@ bool CCryEditDoc::LoadEntitiesFromSlice(const QString& sliceFile)
|
||||
|
||||
bool CCryEditDoc::LoadLevel(TDocMultiArchive& arrXmlAr, const QString& absoluteCryFilePath)
|
||||
{
|
||||
auto pIPak = GetIEditor()->GetSystem()->GetIPak();
|
||||
bool isPrefabEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(isPrefabEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
auto pIPak = GetIEditor()->GetSystem()->GetIPak();
|
||||
|
||||
QString folderPath = QFileInfo(absoluteCryFilePath).absolutePath();
|
||||
|
||||
OnStartLevelResourceList();
|
||||
|
||||
// Load next level resource list.
|
||||
pIPak->GetResourceList(AZ::IO::IArchive::RFOM_NextLevel)->Load(Path::Make(folderPath, "resourcelist.txt").toUtf8().data());
|
||||
if (!isPrefabEnabled)
|
||||
{
|
||||
pIPak->GetResourceList(AZ::IO::IArchive::RFOM_NextLevel)->Load(Path::Make(folderPath, "resourcelist.txt").toUtf8().data());
|
||||
}
|
||||
|
||||
GetIEditor()->Notify(eNotify_OnBeginLoad);
|
||||
CrySystemEventBus::Broadcast(&CrySystemEventBus::Events::OnCryEditorBeginLoad);
|
||||
//GetISystem()->GetISystemEventDispatcher()->OnSystemEvent( ESYSTEM_EVENT_LEVEL_LOAD_START,0,0 );
|
||||
@@ -1719,7 +1843,10 @@ bool CCryEditDoc::LoadLevel(TDocMultiArchive& arrXmlAr, const QString& absoluteC
|
||||
|
||||
GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_END, 0, 0);
|
||||
// We don't need next level resource list anymore.
|
||||
pIPak->GetResourceList(AZ::IO::IArchive::RFOM_NextLevel)->Clear();
|
||||
if (!isPrefabEnabled)
|
||||
{
|
||||
pIPak->GetResourceList(AZ::IO::IArchive::RFOM_NextLevel)->Clear();
|
||||
}
|
||||
SetModifiedFlag(FALSE); // start off with unmodified
|
||||
SetModifiedModules(eModifiedNothing);
|
||||
SetDocumentReady(true);
|
||||
@@ -2309,23 +2436,33 @@ void CCryEditDoc::CreateDefaultLevelAssets(int resolution, int unitSize)
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(m_envProbeSliceAssetId, &AZ::Data::AssetCatalogRequests::GetAssetIdByPath, m_envProbeSliceRelativePath, azrtti_typeid<AZ::SliceAsset>(), false);
|
||||
bool isPrefabSystemEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
isPrefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
if (m_envProbeSliceAssetId.IsValid())
|
||||
if (!isPrefabSystemEnabled)
|
||||
{
|
||||
AZ::Data::Asset<AZ::Data::AssetData> asset = AZ::Data::AssetManager::Instance().FindOrCreateAsset<AZ::SliceAsset>(m_envProbeSliceAssetId, AZ::Data::AssetLoadBehavior::Default);
|
||||
if (asset)
|
||||
{
|
||||
m_terrainSize = resolution * unitSize;
|
||||
const float halfTerrainSize = m_terrainSize / 2.0f;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
m_envProbeSliceAssetId, &AZ::Data::AssetCatalogRequests::GetAssetIdByPath, m_envProbeSliceRelativePath,
|
||||
azrtti_typeid<AZ::SliceAsset>(), false);
|
||||
|
||||
AZ::Transform worldTransform = AZ::Transform::CreateIdentity();
|
||||
worldTransform = AZ::Transform::CreateTranslation(AZ::Vector3(halfTerrainSize, halfTerrainSize, m_envProbeHeight / 2));
|
||||
if (m_envProbeSliceAssetId.IsValid())
|
||||
{
|
||||
AZ::Data::Asset<AZ::Data::AssetData> asset = AZ::Data::AssetManager::Instance().FindOrCreateAsset<AZ::SliceAsset>(
|
||||
m_envProbeSliceAssetId, AZ::Data::AssetLoadBehavior::Default);
|
||||
if (asset)
|
||||
{
|
||||
m_terrainSize = resolution * unitSize;
|
||||
const float halfTerrainSize = m_terrainSize / 2.0f;
|
||||
|
||||
AZ::Transform worldTransform = AZ::Transform::CreateIdentity();
|
||||
worldTransform = AZ::Transform::CreateTranslation(AZ::Vector3(halfTerrainSize, halfTerrainSize, m_envProbeHeight / 2));
|
||||
|
||||
AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler::BusConnect();
|
||||
GetIEditor()->SuspendUndo();
|
||||
AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Broadcast(
|
||||
&AzToolsFramework::SliceEditorEntityOwnershipServiceRequests::InstantiateEditorSlice, asset, worldTransform);
|
||||
AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler::BusConnect();
|
||||
GetIEditor()->SuspendUndo();
|
||||
AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Broadcast(
|
||||
&AzToolsFramework::SliceEditorEntityOwnershipServiceRequests::InstantiateEditorSlice, asset, worldTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,8 +188,6 @@ protected:
|
||||
//! Remove existing mission from map.
|
||||
void RemoveMission(CMission* mission);
|
||||
void LogLoadTime(int time);
|
||||
//! For saving binary data (voxel object)
|
||||
CXmlArchive* GetTmpXmlArch(){ return m_pTmpXmlArchHack; }
|
||||
|
||||
struct TSaveDocContext
|
||||
{
|
||||
@@ -228,7 +226,6 @@ protected:
|
||||
std::vector<CMission*> m_missions;
|
||||
std::list<IDocListener*> m_listeners;
|
||||
bool m_bDocumentReady;
|
||||
CXmlArchive* m_pTmpXmlArchHack;
|
||||
CLevelShaderCache* m_pLevelShaderCache;
|
||||
ICVar* doc_validate_surface_types;
|
||||
int m_modifiedModuleFlags;
|
||||
|
||||
@@ -33,9 +33,6 @@
|
||||
#include "UndoConfigSpec.h"
|
||||
#include "ViewManager.h"
|
||||
|
||||
const char* GetCryEditDefaultFileExtension();
|
||||
const char* GetCryEditOldFileExtension();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
namespace
|
||||
{
|
||||
@@ -111,6 +108,9 @@ namespace
|
||||
|
||||
bool PyOpenLevel(const char* pLevelName)
|
||||
{
|
||||
const char* oldExtension = EditorUtils::LevelFile::GetOldCryFileExtension();
|
||||
const char* defaultExtension = EditorUtils::LevelFile::GetDefaultFileExtension();
|
||||
|
||||
QString levelPath = pLevelName;
|
||||
|
||||
if (!QFile::exists(levelPath))
|
||||
@@ -130,10 +130,10 @@ namespace
|
||||
levelPath = levelsDir / levelPath / levelFileName;
|
||||
|
||||
// make sure the level path includes the cry extension, if needed
|
||||
if (!levelFileName.endsWith(GetCryEditOldFileExtension()) && !levelFileName.endsWith(GetCryEditDefaultFileExtension()))
|
||||
if (!levelFileName.endsWith(oldExtension) && !levelFileName.endsWith(defaultExtension))
|
||||
{
|
||||
QString newLevelPath = levelPath + GetCryEditDefaultFileExtension();
|
||||
QString oldLevelPath = levelPath + GetCryEditOldFileExtension();
|
||||
QString newLevelPath = levelPath + defaultExtension;
|
||||
QString oldLevelPath = levelPath + oldExtension;
|
||||
|
||||
// Check if there is a .cry file, otherwise assume it is a new .ly file
|
||||
if (QFileInfo(oldLevelPath).exists())
|
||||
|
||||
@@ -186,10 +186,9 @@ void CPythonScriptsDialog::OnExecute()
|
||||
|
||||
if (ui->treeView->IsFile(selectedItem))
|
||||
{
|
||||
QString workingDirectory = QDir::currentPath();
|
||||
const QString scriptPath = QStringLiteral("%1/%2").arg(workingDirectory).arg(ui->treeView->GetPath(selectedItem));
|
||||
auto scriptPath = AZ::IO::FixedMaxPath(AZ::Utils::GetEnginePath()) / ui->treeView->GetPath(selectedItem).toUtf8().constData();
|
||||
using namespace AzToolsFramework;
|
||||
EditorPythonRunnerRequestBus::Broadcast(&EditorPythonRunnerRequestBus::Events::ExecuteByFilename, scriptPath.toUtf8().constData());
|
||||
EditorPythonRunnerRequestBus::Broadcast(&EditorPythonRunnerRequestBus::Events::ExecuteByFilename, scriptPath.Native());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ void CEditorFileMonitor::MonitorDirectories()
|
||||
QString RemoveGameName(const QString &filename)
|
||||
{
|
||||
// Remove first part of path. File coming in has the game name included
|
||||
// eg (SamplesProject/Animations/Chicken/anim_chicken_flapping.i_caf)->(Animations/Chicken/anim_chicken_flapping.i_caf)
|
||||
// eg (AutomatedTesting/Animations/Chicken/anim_chicken_flapping.i_caf)->(Animations/Chicken/anim_chicken_flapping.i_caf)
|
||||
|
||||
int indexOfFirstSlash = filename.indexOf('/');
|
||||
int indexOfFirstBackSlash = filename.indexOf('\\');
|
||||
|
||||
@@ -181,15 +181,15 @@ namespace EditorInternal
|
||||
AzFramework::StringFunc::Path::Join(GetGameFolder().c_str(), levelPath.c_str(), levelPath);
|
||||
|
||||
// make sure the level path includes the cry extension, if needed
|
||||
if (!levelFileName.ends_with(OldFileExtension) && !levelFileName.ends_with(DefaultFileExtension))
|
||||
if (!levelFileName.ends_with(GetOldCryLevelExtension()) && !levelFileName.ends_with(GetLevelExtension()))
|
||||
{
|
||||
AZStd::size_t levelPathLength = levelPath.length();
|
||||
levelPath += OldFileExtension;
|
||||
levelPath += GetOldCryLevelExtension();
|
||||
|
||||
// Check if there is a .cry file, otherwise assume it is a new .ly file
|
||||
if (!AZ::IO::SystemFile::Exists(levelPath.c_str()))
|
||||
{
|
||||
levelPath.replace(levelPathLength, sizeof(OldFileExtension) - 1, DefaultFileExtension);
|
||||
levelPath.replace(levelPathLength, sizeof(GetOldCryLevelExtension()) - 1, GetLevelExtension());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,6 +243,27 @@ namespace EditorInternal
|
||||
return AZStd::string(GetIEditor()->GetGameEngine()->GetLevelPath().toUtf8().data());
|
||||
}
|
||||
|
||||
const char* EditorToolsApplication::GetLevelExtension() const
|
||||
{
|
||||
bool prefabSystemEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
prefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
if (!prefabSystemEnabled)
|
||||
{
|
||||
return ".ly";
|
||||
}
|
||||
else
|
||||
{
|
||||
return ".prefab";
|
||||
}
|
||||
}
|
||||
|
||||
const char* EditorToolsApplication::GetOldCryLevelExtension() const
|
||||
{
|
||||
return ".cry";
|
||||
}
|
||||
|
||||
void EditorToolsApplication::Exit()
|
||||
{
|
||||
// Adding a single-shot QTimer to PyExit delays the QApplication::closeAllWindows call until
|
||||
|
||||
@@ -63,9 +63,10 @@ namespace EditorInternal
|
||||
AZStd::string GetCurrentLevelName() const override;
|
||||
AZStd::string GetCurrentLevelPath() const override;
|
||||
|
||||
const char* GetOldCryLevelExtension() const override;
|
||||
const char* GetLevelExtension() const override;
|
||||
|
||||
private:
|
||||
static constexpr char DefaultFileExtension[] = ".ly";
|
||||
static constexpr char OldFileExtension[] = ".cry";
|
||||
static constexpr char DefaultLevelFolder[] = "Levels";
|
||||
|
||||
bool m_StartupAborted = false;
|
||||
|
||||
@@ -41,6 +41,11 @@ namespace EditorInternal
|
||||
virtual AZStd::string GetCurrentLevelName() const = 0;
|
||||
virtual AZStd::string GetCurrentLevelPath() const = 0;
|
||||
|
||||
//! Retrieve old cry level file extension (With prepending '.')
|
||||
virtual const char* GetOldCryLevelExtension() const = 0;
|
||||
//! Retrieve default level file extension (With prepending '.')
|
||||
virtual const char* GetLevelExtension() const = 0;
|
||||
|
||||
virtual void Exit() = 0;
|
||||
virtual void ExitNoPrompt() = 0;
|
||||
};
|
||||
|
||||
@@ -112,20 +112,17 @@ namespace AZ::ViewportHelpers
|
||||
|
||||
class EditorEntityNotifications
|
||||
: public AzToolsFramework::EditorEntityContextNotificationBus::Handler
|
||||
, public AzToolsFramework::EditorEvents::Bus::Handler
|
||||
{
|
||||
public:
|
||||
EditorEntityNotifications(EditorViewportWidget& renderViewport)
|
||||
: m_renderViewport(renderViewport)
|
||||
{
|
||||
AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusConnect();
|
||||
AzToolsFramework::EditorEvents::Bus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
~EditorEntityNotifications() override
|
||||
{
|
||||
AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
// AzToolsFramework::EditorEntityContextNotificationBus
|
||||
@@ -137,12 +134,6 @@ namespace AZ::ViewportHelpers
|
||||
{
|
||||
m_renderViewport.OnStopPlayInEditor();
|
||||
}
|
||||
|
||||
// AzToolsFramework::EditorEvents::Bus
|
||||
void PopulateEditorGlobalContextMenu(QMenu* menu, const AZ::Vector2& point, int flags) override
|
||||
{
|
||||
m_renderViewport.PopulateEditorGlobalContextMenu(menu, point, flags);
|
||||
}
|
||||
private:
|
||||
EditorViewportWidget& m_renderViewport;
|
||||
};
|
||||
@@ -519,26 +510,17 @@ void EditorViewportWidget::Update()
|
||||
PushDisableRendering();
|
||||
|
||||
// draw debug visualizations
|
||||
if (m_debugDisplay)
|
||||
{
|
||||
const AzFramework::DisplayContextRequestGuard displayContextGuard(m_displayContext);
|
||||
|
||||
const AZ::u32 prevState = m_displayContext.GetState();
|
||||
m_displayContext.SetState(
|
||||
const AZ::u32 prevState = m_debugDisplay->GetState();
|
||||
m_debugDisplay->SetState(
|
||||
e_Mode3D | e_AlphaBlended | e_FillModeSolid | e_CullModeBack | e_DepthWriteOn | e_DepthTestOn);
|
||||
|
||||
AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus;
|
||||
AzFramework::DebugDisplayRequestBus::Bind(
|
||||
debugDisplayBus, AzToolsFramework::ViewportInteraction::g_mainViewportEntityDebugDisplayId);
|
||||
AZ_Assert(debugDisplayBus, "Invalid DebugDisplayRequestBus.");
|
||||
|
||||
AzFramework::DebugDisplayRequests* debugDisplay =
|
||||
AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus);
|
||||
|
||||
AzFramework::EntityDebugDisplayEventBus::Broadcast(
|
||||
&AzFramework::EntityDebugDisplayEvents::DisplayEntityViewport,
|
||||
AzFramework::ViewportInfo{ GetViewportId() }, *debugDisplay);
|
||||
AzFramework::ViewportInfo{ GetViewportId() }, *m_debugDisplay);
|
||||
|
||||
m_displayContext.SetState(prevState);
|
||||
m_debugDisplay->SetState(prevState);
|
||||
}
|
||||
|
||||
QtViewport::Update();
|
||||
@@ -571,8 +553,6 @@ void EditorViewportWidget::Update()
|
||||
// 3D engine stats
|
||||
GetIEditor()->GetSystem()->RenderBegin();
|
||||
|
||||
InitDisplayContext();
|
||||
|
||||
OnRender();
|
||||
|
||||
ProcessRenderLisneters(m_displayContext);
|
||||
@@ -825,6 +805,23 @@ void EditorViewportWidget::OnRender()
|
||||
}
|
||||
|
||||
FUNCTION_PROFILER(GetIEditor()->GetSystem(), PROFILE_EDITOR);
|
||||
}
|
||||
|
||||
void EditorViewportWidget::OnBeginPrepareRender()
|
||||
{
|
||||
if (!m_debugDisplay)
|
||||
{
|
||||
AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus;
|
||||
AzFramework::DebugDisplayRequestBus::Bind(debugDisplayBus, GetViewportId());
|
||||
AZ_Assert(debugDisplayBus, "Invalid DebugDisplayRequestBus.");
|
||||
|
||||
m_debugDisplay = AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus);
|
||||
}
|
||||
|
||||
if (!m_debugDisplay)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float fNearZ = GetIEditor()->GetConsoleVar("cl_DefaultNearPlane");
|
||||
float fFarZ = m_Camera.GetFarPlane();
|
||||
@@ -838,8 +835,7 @@ void EditorViewportWidget::OnRender()
|
||||
Camera::CameraRequestBus::EventResult(fNearZ, m_viewEntityId, &Camera::CameraComponentRequests::GetNearClipDistance);
|
||||
Camera::CameraRequestBus::EventResult(fFarZ, m_viewEntityId, &Camera::CameraComponentRequests::GetFarClipDistance);
|
||||
LmbrCentral::EditorCameraCorrectionRequestBus::EventResult(
|
||||
lookThroughEntityCorrection, m_viewEntityId,
|
||||
&LmbrCentral::EditorCameraCorrectionRequests::GetTransformCorrection);
|
||||
lookThroughEntityCorrection, m_viewEntityId, &LmbrCentral::EditorCameraCorrectionRequests::GetTransformCorrection);
|
||||
}
|
||||
|
||||
m_viewTM = cameraObject->GetWorldTM() * AZMatrix3x3ToLYMatrix3x3(lookThroughEntityCorrection);
|
||||
@@ -902,63 +898,31 @@ void EditorViewportWidget::OnRender()
|
||||
|
||||
bool levelIsDisplayable = (ge && ge->IsLevelLoaded() && GetIEditor()->GetDocument() && GetIEditor()->GetDocument()->IsDocumentReady());
|
||||
|
||||
//Handle scene render tasks such as gizmos and handles but only when not in VR
|
||||
if (!m_renderer->IsStereoEnabled())
|
||||
PreWidgetRendering();
|
||||
|
||||
RenderAll();
|
||||
|
||||
// Draw 2D helpers.
|
||||
TransformationMatrices backupSceneMatrices;
|
||||
m_debugDisplay->DepthTestOff();
|
||||
//m_renderer->Set2DMode(m_rcClient.right(), m_rcClient.bottom(), backupSceneMatrices);
|
||||
auto prevState = m_debugDisplay->GetState();
|
||||
m_debugDisplay->SetState(e_Mode3D | e_AlphaBlended | e_FillModeSolid | e_CullModeBack | e_DepthWriteOn | e_DepthTestOn);
|
||||
|
||||
if (gSettings.viewports.bShowSafeFrame)
|
||||
{
|
||||
DisplayContext& displayContext = m_displayContext;
|
||||
|
||||
PreWidgetRendering();
|
||||
|
||||
RenderAll();
|
||||
|
||||
// Draw Axis arrow in lower left corner.
|
||||
if (levelIsDisplayable && !GetIEditor()->IsNewViewportInteractionModelEnabled())
|
||||
{
|
||||
DrawAxis();
|
||||
}
|
||||
|
||||
// Draw 2D helpers.
|
||||
TransformationMatrices backupSceneMatrices;
|
||||
m_renderer->Set2DMode(m_rcClient.right(), m_rcClient.bottom(), backupSceneMatrices);
|
||||
displayContext.SetState(e_Mode3D | e_AlphaBlended | e_FillModeSolid | e_CullModeBack | e_DepthWriteOn | e_DepthTestOn);
|
||||
|
||||
// Display cursor string.
|
||||
RenderCursorString();
|
||||
|
||||
if (gSettings.viewports.bShowSafeFrame)
|
||||
{
|
||||
UpdateSafeFrame();
|
||||
RenderSafeFrame();
|
||||
}
|
||||
|
||||
const AzFramework::DisplayContextRequestGuard displayContextGuard(displayContext);
|
||||
|
||||
AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus;
|
||||
AzFramework::DebugDisplayRequestBus::Bind(
|
||||
debugDisplayBus, AzToolsFramework::ViewportInteraction::g_mainViewportEntityDebugDisplayId);
|
||||
AZ_Assert(debugDisplayBus, "Invalid DebugDisplayRequestBus.");
|
||||
|
||||
AzFramework::DebugDisplayRequests* debugDisplay =
|
||||
AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus);
|
||||
|
||||
AzFramework::ViewportDebugDisplayEventBus::Event(
|
||||
AzToolsFramework::GetEntityContextId(), &AzFramework::ViewportDebugDisplayEvents::DisplayViewport2d,
|
||||
AzFramework::ViewportInfo{ GetViewportId() }, *debugDisplay);
|
||||
|
||||
if (!GetIEditor()->IsNewViewportInteractionModelEnabled())
|
||||
{
|
||||
RenderSelectionRectangle();
|
||||
}
|
||||
|
||||
m_renderer->Unset2DMode(backupSceneMatrices);
|
||||
|
||||
PostWidgetRendering();
|
||||
UpdateSafeFrame();
|
||||
RenderSafeFrame();
|
||||
}
|
||||
|
||||
// TODO: Move out this logic to a controller and refactor to work with Atom
|
||||
//ColorF viewportBackgroundColor(pow(71.0f / 255.0f, 2.2f), pow(71.0f / 255.0f, 2.2f), pow(71.0f / 255.0f, 2.2f));
|
||||
//m_renderer->ClearTargetsLater(FRT_CLEAR_COLOR, viewportBackgroundColor);
|
||||
DrawBackground();
|
||||
AzFramework::ViewportDebugDisplayEventBus::Event(
|
||||
AzToolsFramework::GetEntityContextId(), &AzFramework::ViewportDebugDisplayEvents::DisplayViewport2d,
|
||||
AzFramework::ViewportInfo{GetViewportId()}, *m_debugDisplay);
|
||||
|
||||
m_debugDisplay->SetState(prevState);
|
||||
m_debugDisplay->DepthTestOn();
|
||||
|
||||
PostWidgetRendering();
|
||||
|
||||
if (!m_renderer->IsStereoEnabled())
|
||||
{
|
||||
@@ -966,268 +930,37 @@ void EditorViewportWidget::OnRender()
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void EditorViewportWidget::RenderSelectionRectangle()
|
||||
{
|
||||
if (m_selectedRect.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vec3 topLeft(m_selectedRect.left(), m_selectedRect.top(), 1);
|
||||
Vec3 bottomRight(m_selectedRect.right() +1, m_selectedRect.bottom() + 1, 1);
|
||||
|
||||
m_displayContext.DepthTestOff();
|
||||
m_displayContext.SetColor(1, 1, 1, 0.4f);
|
||||
m_displayContext.DrawWireBox(topLeft, bottomRight);
|
||||
m_displayContext.DepthTestOn();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void EditorViewportWidget::InitDisplayContext()
|
||||
{
|
||||
FUNCTION_PROFILER(GetIEditor()->GetSystem(), PROFILE_EDITOR);
|
||||
|
||||
// Draw all objects.
|
||||
DisplayContext& displayContext = m_displayContext;
|
||||
displayContext.settings = GetIEditor()->GetDisplaySettings();
|
||||
displayContext.view = this;
|
||||
displayContext.renderer = m_renderer;
|
||||
displayContext.engine = m_engine;
|
||||
displayContext.box.min = Vec3(-100000.0f, -100000.0f, -100000.0f);
|
||||
displayContext.box.max = Vec3(100000.0f, 100000.0f, 100000.0f);
|
||||
displayContext.camera = &m_Camera;
|
||||
displayContext.flags = 0;
|
||||
|
||||
if (!displayContext.settings->IsDisplayLabels() || !displayContext.settings->IsDisplayHelpers())
|
||||
{
|
||||
displayContext.flags |= DISPLAY_HIDENAMES;
|
||||
}
|
||||
|
||||
if (displayContext.settings->IsDisplayLinks() && displayContext.settings->IsDisplayHelpers())
|
||||
{
|
||||
displayContext.flags |= DISPLAY_LINKS;
|
||||
}
|
||||
|
||||
if (m_bDegradateQuality)
|
||||
{
|
||||
displayContext.flags |= DISPLAY_DEGRADATED;
|
||||
}
|
||||
|
||||
if (displayContext.settings->GetRenderFlags() & RENDER_FLAG_BBOX)
|
||||
{
|
||||
displayContext.flags |= DISPLAY_BBOX;
|
||||
}
|
||||
|
||||
if (displayContext.settings->IsDisplayTracks() && displayContext.settings->IsDisplayHelpers())
|
||||
{
|
||||
displayContext.flags |= DISPLAY_TRACKS;
|
||||
displayContext.flags |= DISPLAY_TRACKTICKS;
|
||||
}
|
||||
|
||||
if (m_bAdvancedSelectMode && !GetIEditor()->IsNewViewportInteractionModelEnabled())
|
||||
{
|
||||
displayContext.flags |= DISPLAY_SELECTION_HELPERS;
|
||||
}
|
||||
|
||||
if (GetIEditor()->GetReferenceCoordSys() == COORDS_WORLD)
|
||||
{
|
||||
displayContext.flags |= DISPLAY_WORLDSPACEAXIS;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void EditorViewportWidget::PopulateEditorGlobalContextMenu(QMenu* /*menu*/, const AZ::Vector2& /*point*/, int /*flags*/)
|
||||
{
|
||||
m_bInMoveMode = false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void EditorViewportWidget::RenderAll()
|
||||
{
|
||||
// Draw all objects.
|
||||
DisplayContext& displayContext = m_displayContext;
|
||||
|
||||
displayContext.SetState(e_Mode3D | e_AlphaBlended | e_FillModeSolid | e_CullModeBack | e_DepthWriteOn | e_DepthTestOn);
|
||||
GetIEditor()->GetObjectManager()->Display(displayContext);
|
||||
|
||||
RenderSelectedRegion();
|
||||
|
||||
RenderSnapMarker();
|
||||
|
||||
if (gSettings.viewports.bShowGridGuide
|
||||
&& GetIEditor()->GetDisplaySettings()->IsDisplayHelpers())
|
||||
{
|
||||
RenderSnappingGrid();
|
||||
}
|
||||
|
||||
if (displayContext.settings->GetDebugFlags() & DBG_MEMINFO)
|
||||
{
|
||||
ProcessMemInfo mi;
|
||||
CProcessInfo::QueryMemInfo(mi);
|
||||
int MB = 1024 * 1024;
|
||||
QString str = QStringLiteral("WorkingSet=%1Mb, PageFile=%2Mb, PageFaults=%3").arg(mi.WorkingSet / MB).arg(mi.PagefileUsage / MB).arg(mi.PageFaultCount);
|
||||
m_renderer->TextToScreenColor(1, 1, 1, 0, 0, 1, str.toUtf8().data());
|
||||
}
|
||||
|
||||
{
|
||||
const AzFramework::DisplayContextRequestGuard displayContextGuard(displayContext);
|
||||
|
||||
AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus;
|
||||
AzFramework::DebugDisplayRequestBus::Bind(
|
||||
debugDisplayBus, AzToolsFramework::ViewportInteraction::g_mainViewportEntityDebugDisplayId);
|
||||
AZ_Assert(debugDisplayBus, "Invalid DebugDisplayRequestBus.");
|
||||
|
||||
AzFramework::DebugDisplayRequests* debugDisplay =
|
||||
AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus);
|
||||
|
||||
// allow the override of in-editor visualization
|
||||
AzFramework::ViewportDebugDisplayEventBus::Event(
|
||||
AzToolsFramework::GetEntityContextId(), &AzFramework::ViewportDebugDisplayEvents::DisplayViewport,
|
||||
AzFramework::ViewportInfo{ GetViewportId() }, *debugDisplay);
|
||||
|
||||
m_entityVisibilityQuery.DisplayVisibility(*debugDisplay);
|
||||
|
||||
if (GetEditTool())
|
||||
{
|
||||
// display editing tool
|
||||
GetEditTool()->Display(displayContext);
|
||||
}
|
||||
|
||||
if (m_manipulatorManager != nullptr)
|
||||
{
|
||||
using namespace AzToolsFramework::ViewportInteraction;
|
||||
|
||||
debugDisplay->DepthTestOff();
|
||||
m_manipulatorManager->DrawManipulators(
|
||||
*debugDisplay, GetCameraState(),
|
||||
BuildMouseInteractionInternal(
|
||||
MouseButtons(TranslateMouseButtons(QGuiApplication::mouseButtons())),
|
||||
BuildKeyboardModifiers(QGuiApplication::queryKeyboardModifiers()),
|
||||
BuildMousePickInternal(WidgetToViewport(mapFromGlobal(QCursor::pos())))));
|
||||
debugDisplay->DepthTestOn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void EditorViewportWidget::DrawAxis()
|
||||
{
|
||||
AZ_Assert(m_cameraSetForWidgetRenderingCount > 0,
|
||||
"DrawAxis was called but viewport widget rendering was not set. PreWidgetRendering must be called before.");
|
||||
|
||||
DisplayContext& dc = m_displayContext;
|
||||
|
||||
// show axis only if draw helpers is activated
|
||||
if (!dc.settings->IsDisplayHelpers())
|
||||
if (!m_debugDisplay)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vec3 colX(1, 0, 0), colY(0, 1, 0), colZ(0, 0, 1), colW(1, 1, 1);
|
||||
Vec3 pos(50, 50, 0.1f); // Bottom-left corner
|
||||
// allow the override of in-editor visualization
|
||||
AzFramework::ViewportDebugDisplayEventBus::Event(
|
||||
AzToolsFramework::GetEntityContextId(), &AzFramework::ViewportDebugDisplayEvents::DisplayViewport,
|
||||
AzFramework::ViewportInfo{ GetViewportId() }, *m_debugDisplay);
|
||||
|
||||
float wx, wy, wz;
|
||||
UnProjectFromScreen(pos.x, pos.y, pos.z, &wx, &wy, &wz);
|
||||
Vec3 posInWorld(wx, wy, wz);
|
||||
float screenScale = GetScreenScaleFactor(posInWorld);
|
||||
float length = 0.03f * screenScale;
|
||||
float arrowSize = 0.02f * screenScale;
|
||||
float textSize = 1.1f;
|
||||
m_entityVisibilityQuery.DisplayVisibility(*m_debugDisplay);
|
||||
|
||||
Vec3 x(length, 0, 0);
|
||||
Vec3 y(0, length, 0);
|
||||
Vec3 z(0, 0, length);
|
||||
if (m_manipulatorManager != nullptr)
|
||||
{
|
||||
using namespace AzToolsFramework::ViewportInteraction;
|
||||
|
||||
int prevRState = dc.GetState();
|
||||
dc.DepthWriteOff();
|
||||
dc.DepthTestOff();
|
||||
dc.CullOff();
|
||||
dc.SetLineWidth(1);
|
||||
|
||||
dc.SetColor(colX);
|
||||
dc.DrawLine(posInWorld, posInWorld + x);
|
||||
dc.DrawArrow(posInWorld + x * 0.9f, posInWorld + x, arrowSize);
|
||||
dc.SetColor(colY);
|
||||
dc.DrawLine(posInWorld, posInWorld + y);
|
||||
dc.DrawArrow(posInWorld + y * 0.9f, posInWorld + y, arrowSize);
|
||||
dc.SetColor(colZ);
|
||||
dc.DrawLine(posInWorld, posInWorld + z);
|
||||
dc.DrawArrow(posInWorld + z * 0.9f, posInWorld + z, arrowSize);
|
||||
|
||||
dc.SetColor(colW);
|
||||
dc.DrawTextLabel(posInWorld + x, textSize, "x");
|
||||
dc.DrawTextLabel(posInWorld + y, textSize, "y");
|
||||
dc.DrawTextLabel(posInWorld + z, textSize, "z");
|
||||
|
||||
dc.DepthWriteOn();
|
||||
dc.DepthTestOn();
|
||||
dc.CullOn();
|
||||
dc.SetState(prevRState);
|
||||
m_debugDisplay->DepthTestOff();
|
||||
m_manipulatorManager->DrawManipulators(
|
||||
*m_debugDisplay, GetCameraState(),
|
||||
BuildMouseInteractionInternal(
|
||||
MouseButtons(TranslateMouseButtons(QGuiApplication::mouseButtons())),
|
||||
BuildKeyboardModifiers(QGuiApplication::queryKeyboardModifiers()),
|
||||
BuildMousePickInternal(WidgetToViewport(mapFromGlobal(QCursor::pos())))));
|
||||
m_debugDisplay->DepthTestOn();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void EditorViewportWidget::DrawBackground()
|
||||
{
|
||||
DisplayContext& dc = m_displayContext;
|
||||
|
||||
if (!dc.settings->IsDisplayHelpers()) // show gradient bg only if draw helpers are activated
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int heightVP = width();
|
||||
int widthVP = height();
|
||||
Vec3 pos(0, 0, 0);
|
||||
|
||||
Vec3 x(widthVP, 0, 0);
|
||||
Vec3 y(0, heightVP, 0);
|
||||
|
||||
float height = m_rcClient.height();
|
||||
|
||||
auto NegY = [](const Vec3& v, float y) -> Vec3
|
||||
{
|
||||
return Vec3(v.x, y - v.y, v.z);
|
||||
};
|
||||
|
||||
Vec3 src = NegY(pos, height);
|
||||
Vec3 trgx = NegY(pos + x, height);
|
||||
Vec3 trgy = NegY(pos + y, height);
|
||||
|
||||
QColor topColor = palette().color(QPalette::Window);
|
||||
QColor bottomColor = palette().color(QPalette::Disabled, QPalette::WindowText);
|
||||
|
||||
ColorB firstC(topColor.red(), topColor.green(), topColor.blue(), 255.0f);
|
||||
ColorB secondC(bottomColor.red(), bottomColor.green(), bottomColor.blue(), 255.0f);
|
||||
|
||||
TransformationMatrices backupSceneMatrices;
|
||||
|
||||
m_renderer->Set2DMode(m_rcClient.right(), m_rcClient.bottom(), backupSceneMatrices);
|
||||
m_displayContext.SetState(e_Mode3D | e_AlphaBlended | e_FillModeSolid | e_CullModeBack | e_DepthWriteOn | e_DepthTestOn);
|
||||
dc.DrawQuadGradient(src, trgx, pos + x, pos, secondC, firstC);
|
||||
m_renderer->Unset2DMode(backupSceneMatrices);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void EditorViewportWidget::RenderCursorString()
|
||||
{
|
||||
if (m_cursorStr.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto point = WidgetToViewport(mapFromGlobal(QCursor::pos()));
|
||||
|
||||
// Display hit object name.
|
||||
float col[4] = { 1, 1, 1, 1 };
|
||||
m_renderer->Draw2dLabel(point.x() + 12, point.y() + 4, 1.2f, col, false, "%s", m_cursorStr.toUtf8().data());
|
||||
|
||||
if (!m_cursorSupplementaryStr.isEmpty())
|
||||
{
|
||||
float col2[4] = { 1, 1, 0, 1 };
|
||||
m_renderer->Draw2dLabel(point.x() + 12, point.y() + 4 + CURSOR_FONT_HEIGHT * 1.2f, 1.2f, col2, false, "%s", m_cursorSupplementaryStr.toUtf8().data());
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void EditorViewportWidget::UpdateSafeFrame()
|
||||
@@ -1285,14 +1018,14 @@ void EditorViewportWidget::RenderSafeFrame()
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void EditorViewportWidget::RenderSafeFrame(const QRect& frame, float r, float g, float b, float a)
|
||||
{
|
||||
m_displayContext.SetColor(r, g, b, a);
|
||||
m_debugDisplay->SetColor(r, g, b, a);
|
||||
|
||||
const int LINE_WIDTH = 2;
|
||||
for (int i = 0; i < LINE_WIDTH; i++)
|
||||
{
|
||||
Vec3 topLeft(frame.left() + i, frame.top() + i, 0);
|
||||
Vec3 bottomRight(frame.right() - i, frame.bottom() - i, 0);
|
||||
m_displayContext.DrawWireBox(topLeft, bottomRight);
|
||||
AZ::Vector3 topLeft(frame.left() + i, frame.top() + i, 0);
|
||||
AZ::Vector3 bottomRight(frame.right() - i, frame.bottom() - i, 0);
|
||||
m_debugDisplay->DrawWireBox(topLeft, bottomRight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2917,195 +2650,6 @@ void EditorViewportWidget::OnStopPlayInEditor()
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void EditorViewportWidget::RenderConstructionPlane()
|
||||
{
|
||||
DisplayContext& dc = m_displayContext;
|
||||
|
||||
int prevState = dc.GetState();
|
||||
dc.DepthWriteOff();
|
||||
// Draw Construction plane.
|
||||
|
||||
CGrid* pGrid = GetViewManager()->GetGrid();
|
||||
|
||||
RefCoordSys coordSys = COORDS_WORLD;
|
||||
|
||||
Vec3 p = m_constructionMatrix[coordSys].GetTranslation();
|
||||
Vec3 n = m_constructionPlane.n;
|
||||
|
||||
Vec3 u = Vec3(1, 0, 0);
|
||||
Vec3 v = Vec3(0, 1, 0);
|
||||
|
||||
|
||||
if (gSettings.snap.bGridUserDefined)
|
||||
{
|
||||
Ang3 angles = Ang3(pGrid->rotationAngles.x * gf_PI / 180.0, pGrid->rotationAngles.y * gf_PI / 180.0, pGrid->rotationAngles.z * gf_PI / 180.0);
|
||||
Matrix34 tm = Matrix33::CreateRotationXYZ(angles);
|
||||
|
||||
if (gSettings.snap.bGridGetFromSelected)
|
||||
{
|
||||
CSelectionGroup* sel = GetIEditor()->GetSelection();
|
||||
if (sel->GetCount() > 0)
|
||||
{
|
||||
CBaseObject* obj = sel->GetObject(0);
|
||||
tm = obj->GetWorldTM();
|
||||
tm.OrthonormalizeFast();
|
||||
tm.SetTranslation(Vec3(0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
u = tm * u;
|
||||
v = tm * v;
|
||||
}
|
||||
|
||||
float step = pGrid->scale * pGrid->size;
|
||||
float size = gSettings.snap.constructPlaneSize;
|
||||
|
||||
dc.SetColor(0, 0, 1, 0.1f);
|
||||
|
||||
float s = size;
|
||||
|
||||
dc.DrawQuad(p - u * s - v * s, p + u * s - v * s, p + u * s + v * s, p - u * s + v * s);
|
||||
|
||||
int nSteps = int(size / step);
|
||||
int i;
|
||||
// Draw X lines.
|
||||
dc.SetColor(1, 0, 0.2f, 0.3f);
|
||||
|
||||
for (i = -nSteps; i <= nSteps; i++)
|
||||
{
|
||||
dc.DrawLine(p - u * size + v * (step * i), p + u * size + v * (step * i));
|
||||
}
|
||||
// Draw Y lines.
|
||||
dc.SetColor(0.2f, 1.0f, 0, 0.3f);
|
||||
for (i = -nSteps; i <= nSteps; i++)
|
||||
{
|
||||
dc.DrawLine(p - v * size + u * (step * i), p + v * size + u * (step * i));
|
||||
}
|
||||
|
||||
// Draw origin lines.
|
||||
|
||||
dc.SetLineWidth(2);
|
||||
|
||||
//X
|
||||
dc.SetColor(1, 0, 0);
|
||||
dc.DrawLine(p - u * s, p + u * s);
|
||||
|
||||
//Y
|
||||
dc.SetColor(0, 1, 0);
|
||||
dc.DrawLine(p - v * s, p + v * s);
|
||||
|
||||
//Z
|
||||
dc.SetColor(0, 0, 1);
|
||||
dc.DrawLine(p - n * s, p + n * s);
|
||||
|
||||
dc.SetLineWidth(0);
|
||||
|
||||
dc.SetState(prevState);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void EditorViewportWidget::RenderSnappingGrid()
|
||||
{
|
||||
// First, Check whether we should draw the grid or not.
|
||||
CSelectionGroup* pSelGroup = GetIEditor()->GetSelection();
|
||||
if (pSelGroup == nullptr || pSelGroup->GetCount() != 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (GetIEditor()->GetEditMode() != eEditModeMove
|
||||
&& GetIEditor()->GetEditMode() != eEditModeRotate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CGrid* pGrid = GetViewManager()->GetGrid();
|
||||
if (pGrid->IsEnabled() == false && pGrid->IsAngleSnapEnabled() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (GetIEditor()->GetEditTool() && !GetIEditor()->GetEditTool()->IsDisplayGrid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DisplayContext& dc = m_displayContext;
|
||||
|
||||
int prevState = dc.GetState();
|
||||
dc.DepthWriteOff();
|
||||
|
||||
Vec3 p = pSelGroup->GetObject(0)->GetWorldPos();
|
||||
|
||||
AABB bbox;
|
||||
pSelGroup->GetObject(0)->GetBoundBox(bbox);
|
||||
float size = 2 * bbox.GetRadius();
|
||||
float alphaMax = 1.0f, alphaMin = 0.2f;
|
||||
dc.SetLineWidth(3);
|
||||
|
||||
if (GetIEditor()->GetEditMode() == eEditModeMove && pGrid->IsEnabled())
|
||||
// Draw the translation grid.
|
||||
{
|
||||
Vec3 u = m_constructionPlaneAxisX;
|
||||
Vec3 v = m_constructionPlaneAxisY;
|
||||
float step = pGrid->scale * pGrid->size;
|
||||
const int MIN_STEP_COUNT = 5;
|
||||
const int MAX_STEP_COUNT = 300;
|
||||
int nSteps = std::min(std::max(FloatToIntRet(size / step), MIN_STEP_COUNT), MAX_STEP_COUNT);
|
||||
size = nSteps * step;
|
||||
for (int i = -nSteps; i <= nSteps; ++i)
|
||||
{
|
||||
// Draw u lines.
|
||||
float alphaCur = alphaMax - fabsf(float(i) / float(nSteps)) * (alphaMax - alphaMin);
|
||||
dc.DrawLine(p + v * (step * i), p + u * size + v * (step * i),
|
||||
ColorF(0, 0, 0, alphaCur), ColorF(0, 0, 0, alphaMin));
|
||||
dc.DrawLine(p + v * (step * i), p - u * size + v * (step * i),
|
||||
ColorF(0, 0, 0, alphaCur), ColorF(0, 0, 0, alphaMin));
|
||||
// Draw v lines.
|
||||
dc.DrawLine(p + u * (step * i), p + v * size + u * (step * i),
|
||||
ColorF(0, 0, 0, alphaCur), ColorF(0, 0, 0, alphaMin));
|
||||
dc.DrawLine(p + u * (step * i), p - v * size + u * (step * i),
|
||||
ColorF(0, 0, 0, alphaCur), ColorF(0, 0, 0, alphaMin));
|
||||
}
|
||||
}
|
||||
else if (GetIEditor()->GetEditMode() == eEditModeRotate && pGrid->IsAngleSnapEnabled())
|
||||
// Draw the rotation grid.
|
||||
{
|
||||
int nAxis(GetAxisConstrain());
|
||||
if (nAxis == AXIS_X || nAxis == AXIS_Y || nAxis == AXIS_Z)
|
||||
{
|
||||
RefCoordSys coordSys = GetIEditor()->GetReferenceCoordSys();
|
||||
Vec3 xAxis(1, 0, 0);
|
||||
Vec3 yAxis(0, 1, 0);
|
||||
Vec3 zAxis(0, 0, 1);
|
||||
Vec3 rotAxis;
|
||||
if (nAxis == AXIS_X)
|
||||
{
|
||||
rotAxis = m_constructionMatrix[coordSys].TransformVector(xAxis);
|
||||
}
|
||||
else if (nAxis == AXIS_Y)
|
||||
{
|
||||
rotAxis = m_constructionMatrix[coordSys].TransformVector(yAxis);
|
||||
}
|
||||
else if (nAxis == AXIS_Z)
|
||||
{
|
||||
rotAxis = m_constructionMatrix[coordSys].TransformVector(zAxis);
|
||||
}
|
||||
Vec3 anotherAxis = m_constructionPlane.n * size;
|
||||
float step = pGrid->angleSnap;
|
||||
int nSteps = FloatToIntRet(180.0f / step);
|
||||
for (int i = 0; i < nSteps; ++i)
|
||||
{
|
||||
AngleAxis rot(i* step* gf_PI / 180.0, rotAxis);
|
||||
Vec3 dir = rot * anotherAxis;
|
||||
dc.DrawLine(p, p + dir,
|
||||
ColorF(0, 0, 0, alphaMax), ColorF(0, 0, 0, alphaMin));
|
||||
dc.DrawLine(p, p - dir,
|
||||
ColorF(0, 0, 0, alphaMax), ColorF(0, 0, 0, alphaMin));
|
||||
}
|
||||
}
|
||||
}
|
||||
dc.SetState(prevState);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
EditorViewportWidget::SPreviousContext EditorViewportWidget::SetCurrentContext(int /*newWidth*/, int /*newHeight*/) const
|
||||
{
|
||||
@@ -3320,7 +2864,10 @@ void EditorViewportWidget::UpdateScene()
|
||||
AzFramework::SceneSystemRequestBus::BroadcastResult(scenes, &AzFramework::SceneSystemRequests::GetAllScenes);
|
||||
if (scenes.size() > 0)
|
||||
{
|
||||
m_renderViewport->SetScene(scenes[0]);
|
||||
AZ::RPI::SceneNotificationBus::Handler::BusDisconnect();
|
||||
auto scene = scenes[0];
|
||||
m_renderViewport->SetScene(scene);
|
||||
AZ::RPI::SceneNotificationBus::Handler::BusConnect(m_renderViewport->GetViewportContext()->GetRenderScene()->GetId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
#include <MathConversion.h>
|
||||
#include <Atom/RPI.Public/ViewportContext.h>
|
||||
#include <Atom/RPI.Public/SceneBus.h>
|
||||
#endif
|
||||
|
||||
#include <AzFramework/Windowing/WindowBus.h>
|
||||
@@ -76,6 +77,7 @@ class SANDBOX_API EditorViewportWidget
|
||||
, public AzToolsFramework::ViewportInteraction::ViewportFreezeRequestBus::Handler
|
||||
, public AzToolsFramework::ViewportInteraction::MainEditorViewportInteractionRequestBus::Handler
|
||||
, public AzFramework::AssetCatalogEventBus::Handler
|
||||
, public AZ::RPI::SceneNotificationBus::Handler
|
||||
{
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
|
||||
@@ -187,10 +189,6 @@ public:
|
||||
virtual void OnStartPlayInEditor();
|
||||
virtual void OnStopPlayInEditor();
|
||||
|
||||
// AzToolsFramework::EditorEvents::Bus (handler moved to cpp to resolve link issues in unity builds)
|
||||
// We use this to determine when the viewport context menu is being displayed so we can exit move mode
|
||||
void PopulateEditorGlobalContextMenu(QMenu* /*menu*/, const AZ::Vector2& /*point*/, int /*flags*/);
|
||||
|
||||
// AzToolsFramework::ViewportInteractionRequestBus
|
||||
AzFramework::CameraState GetCameraState();
|
||||
bool GridSnappingEnabled();
|
||||
@@ -353,13 +351,8 @@ protected:
|
||||
|
||||
void RenderConstructionPlane();
|
||||
void RenderSnapMarker();
|
||||
void RenderCursorString();
|
||||
void RenderSnappingGrid();
|
||||
|
||||
void RenderAll();
|
||||
void DrawAxis();
|
||||
void DrawBackground();
|
||||
void InitDisplayContext();
|
||||
|
||||
struct SPreviousContext
|
||||
{
|
||||
@@ -381,6 +374,7 @@ protected:
|
||||
|
||||
void PreWidgetRendering() override;
|
||||
void PostWidgetRendering() override;
|
||||
void OnBeginPrepareRender() override;
|
||||
|
||||
// Update the safe frame, safe action, safe title, and borders rectangles based on
|
||||
// viewport size and target aspect ratio.
|
||||
@@ -392,9 +386,6 @@ protected:
|
||||
// Draw one of the safe frame rectangles with the desired color.
|
||||
void RenderSafeFrame(const QRect& frame, float r, float g, float b, float a);
|
||||
|
||||
// Draw the selection rectangle.
|
||||
void RenderSelectionRectangle();
|
||||
|
||||
// Draw a selected region if it has been selected
|
||||
void RenderSelectedRegion();
|
||||
|
||||
@@ -634,6 +625,7 @@ private:
|
||||
bool m_updatingCameraPosition = false;
|
||||
AZ::RPI::ViewportContext::MatrixChangedEvent::Handler m_cameraViewMatrixChangeHandler;
|
||||
AZ::RPI::ViewportContext::MatrixChangedEvent::Handler m_cameraProjectionMatrixChangeHandler;
|
||||
AzFramework::DebugDisplayRequests* m_debugDisplay = nullptr;
|
||||
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
};
|
||||
|
||||
@@ -61,10 +61,6 @@
|
||||
// Including this too early will result in a linker error
|
||||
#include <CryCommon/CryLibrary.h>
|
||||
|
||||
|
||||
static const char defaultFileExtension[] = ".ly";
|
||||
static const char oldFileExtension[] = ".cry";
|
||||
|
||||
// Implementation of System Callback structure.
|
||||
struct SSystemUserCallback
|
||||
: public ISystemUserCallback
|
||||
@@ -274,7 +270,7 @@ AZ_POP_DISABLE_WARNING
|
||||
m_hSystemHandle = 0;
|
||||
m_bJustCreated = false;
|
||||
m_levelName = "Untitled";
|
||||
m_levelExtension = defaultFileExtension;
|
||||
m_levelExtension = EditorUtils::LevelFile::GetDefaultFileExtension();
|
||||
m_playerViewTM.SetIdentity();
|
||||
GetIEditor()->RegisterNotifyListener(this);
|
||||
AZ::Interface<IEditorCameraController>::Register(this);
|
||||
@@ -541,14 +537,17 @@ void CGameEngine::SetLevelPath(const QString& path)
|
||||
|
||||
m_levelName = m_levelPath.mid(m_levelPath.lastIndexOf('/') + 1);
|
||||
|
||||
const char* oldExtension = EditorUtils::LevelFile::GetOldCryFileExtension();
|
||||
const char* defaultExtension = EditorUtils::LevelFile::GetDefaultFileExtension();
|
||||
|
||||
// Store off if
|
||||
if (QFileInfo(path + oldFileExtension).exists())
|
||||
if (QFileInfo(path + oldExtension).exists())
|
||||
{
|
||||
m_levelExtension = oldFileExtension;
|
||||
m_levelExtension = oldExtension;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_levelExtension = defaultFileExtension;
|
||||
m_levelExtension = defaultExtension;
|
||||
}
|
||||
|
||||
if (gEnv->p3DEngine)
|
||||
@@ -576,12 +575,20 @@ bool CGameEngine::LoadLevel(
|
||||
// directory is wrong
|
||||
QDir::setCurrent(GetIEditor()->GetPrimaryCDFolder());
|
||||
|
||||
QString pakFile = m_levelPath + "/level.pak";
|
||||
|
||||
// Open Pak file for this level.
|
||||
if (!m_pISystem->GetIPak()->OpenPack(m_levelPath.toUtf8().data(), pakFile.toUtf8().data()))
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
|
||||
if (!usePrefabSystemForLevels)
|
||||
{
|
||||
CryWarning(VALIDATOR_MODULE_EDITOR, VALIDATOR_WARNING, "Level Pack File %s Not Found", pakFile.toUtf8().data());
|
||||
QString pakFile = m_levelPath + "/level.pak";
|
||||
|
||||
// Open Pak file for this level.
|
||||
if (!m_pISystem->GetIPak()->OpenPack(m_levelPath.toUtf8().data(), pakFile.toUtf8().data()))
|
||||
{
|
||||
CryWarning(VALIDATOR_MODULE_EDITOR, VALIDATOR_WARNING, "Level Pack File %s Not Found", pakFile.toUtf8().data());
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize physics grid.
|
||||
|
||||
@@ -108,151 +108,162 @@ bool CGameExporter::Export(unsigned int flags, [[maybe_unused]] EEndian eExportE
|
||||
bool exportSuccessful = true;
|
||||
|
||||
CrySystemEventBus::Broadcast(&CrySystemEventBus::Events::OnCryEditorBeginLevelExport);
|
||||
pEditor->Notify(eNotify_OnBeginExportToGame);
|
||||
|
||||
CObjectManager* pObjectManager = static_cast<CObjectManager*>(pEditor->GetObjectManager());
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
|
||||
QDir::setCurrent(pEditor->GetPrimaryCDFolder());
|
||||
|
||||
// Close all Editor tools
|
||||
pEditor->SetEditTool(0);
|
||||
|
||||
QString sLevelPath = Path::AddSlash(pGameEngine->GetLevelPath());
|
||||
if (subdirectory && subdirectory[0] && strcmp(subdirectory, ".") != 0)
|
||||
if (usePrefabSystemForLevels)
|
||||
{
|
||||
sLevelPath = Path::AddSlash(sLevelPath + subdirectory);
|
||||
QDir().mkpath(sLevelPath);
|
||||
}
|
||||
|
||||
m_levelPak.m_sPath = QString(sLevelPath) + GetLevelPakFilename();
|
||||
|
||||
m_levelPath = Path::RemoveBackslash(sLevelPath);
|
||||
QString rootLevelPath = Path::AddSlash(pGameEngine->GetLevelPath());
|
||||
|
||||
// Make sure we unload any unused CGFs before exporting so that they don't end up in
|
||||
// the level data.
|
||||
pEditor->Get3DEngine()->FreeUnusedCGFResources();
|
||||
|
||||
CCryEditDoc* pDocument = pEditor->GetDocument();
|
||||
|
||||
if (flags & eExp_Fast)
|
||||
{
|
||||
m_settings.SetLowQuality();
|
||||
}
|
||||
else if (m_bAutoExportMode)
|
||||
{
|
||||
m_settings.SetHiQuality();
|
||||
}
|
||||
|
||||
CryAutoLock<CryMutex> autoLock(CGameEngine::GetPakModifyMutex());
|
||||
|
||||
// Close this pak file.
|
||||
if (!CloseLevelPack(m_levelPak, true))
|
||||
{
|
||||
Error("Cannot close Pak file " + m_levelPak.m_sPath);
|
||||
exportSuccessful = false;
|
||||
}
|
||||
|
||||
if (exportSuccessful)
|
||||
{
|
||||
if (m_bAutoExportMode)
|
||||
{
|
||||
// Remove read-only flags.
|
||||
CrySetFileAttributes(m_levelPak.m_sPath.toUtf8().data(), FILE_ATTRIBUTE_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (exportSuccessful)
|
||||
{
|
||||
if (!CFileUtil::OverwriteFile(m_levelPak.m_sPath))
|
||||
{
|
||||
Error("Cannot overwrite Pak file " + m_levelPak.m_sPath);
|
||||
exportSuccessful = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (exportSuccessful)
|
||||
{
|
||||
if (!OpenLevelPack(m_levelPak, false))
|
||||
{
|
||||
Error("Cannot open Pak file " + m_levelPak.m_sPath + " for writing.");
|
||||
exportSuccessful = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Inform all objects that an export is about to begin
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
if (exportSuccessful)
|
||||
{
|
||||
GetIEditor()->GetObjectManager()->GetPhysicsManager()->PrepareForExport();
|
||||
GetIEditor()->GetObjectManager()->SendEvent(EVENT_PRE_EXPORT);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Export all data to the game
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
if (exportSuccessful)
|
||||
{
|
||||
ExportVisAreas(sLevelPath.toUtf8().data(), eExportEndian);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Exporting map setttings
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
ExportOcclusionMesh(sLevelPath.toUtf8().data());
|
||||
|
||||
//! Export Level data.
|
||||
CLogFile::WriteLine("Exporting LevelData.xml");
|
||||
ExportLevelData(sLevelPath);
|
||||
CLogFile::WriteLine("Exporting LevelData.xml done.");
|
||||
|
||||
ExportLevelInfo(sLevelPath);
|
||||
|
||||
ExportLevelLensFlares(sLevelPath);
|
||||
ExportLevelResourceList(sLevelPath);
|
||||
ExportLevelUsedResourceList(sLevelPath);
|
||||
ExportLevelShaderCache(sLevelPath);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// End Exporting Game data.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Close all packs.
|
||||
CloseLevelPack(m_levelPak, false);
|
||||
// m_texturePakFile.Close();
|
||||
|
||||
pEditor->SetStatusText(QObject::tr("Ready"));
|
||||
|
||||
// Reopen this pak file.
|
||||
if (!OpenLevelPack(m_levelPak, true))
|
||||
{
|
||||
Error("Cannot open Pak file " + m_levelPak.m_sPath);
|
||||
exportSuccessful = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (exportSuccessful)
|
||||
{
|
||||
// Commit changes to the disk.
|
||||
_flushall();
|
||||
|
||||
// finally create filelist.xml
|
||||
QString levelName = Path::GetFileName(pGameEngine->GetLevelPath());
|
||||
ExportFileList(sLevelPath, levelName);
|
||||
// Level.pak and all the data contained within it is unused when using the prefab system for levels, so there's nothing
|
||||
// to do here.
|
||||
|
||||
CCryEditDoc* pDocument = pEditor->GetDocument();
|
||||
pDocument->SetLevelExported(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
CObjectManager* pObjectManager = static_cast<CObjectManager*>(pEditor->GetObjectManager());
|
||||
|
||||
QDir::setCurrent(pEditor->GetPrimaryCDFolder());
|
||||
|
||||
// Close all Editor tools
|
||||
pEditor->SetEditTool(0);
|
||||
|
||||
QString sLevelPath = Path::AddSlash(pGameEngine->GetLevelPath());
|
||||
if (subdirectory && subdirectory[0] && strcmp(subdirectory, ".") != 0)
|
||||
{
|
||||
sLevelPath = Path::AddSlash(sLevelPath + subdirectory);
|
||||
QDir().mkpath(sLevelPath);
|
||||
}
|
||||
|
||||
m_levelPak.m_sPath = QString(sLevelPath) + GetLevelPakFilename();
|
||||
|
||||
m_levelPath = Path::RemoveBackslash(sLevelPath);
|
||||
QString rootLevelPath = Path::AddSlash(pGameEngine->GetLevelPath());
|
||||
|
||||
// Make sure we unload any unused CGFs before exporting so that they don't end up in
|
||||
// the level data.
|
||||
pEditor->Get3DEngine()->FreeUnusedCGFResources();
|
||||
|
||||
CCryEditDoc* pDocument = pEditor->GetDocument();
|
||||
|
||||
if (flags & eExp_Fast)
|
||||
{
|
||||
m_settings.SetLowQuality();
|
||||
}
|
||||
else if (m_bAutoExportMode)
|
||||
{
|
||||
m_settings.SetHiQuality();
|
||||
}
|
||||
|
||||
CryAutoLock<CryMutex> autoLock(CGameEngine::GetPakModifyMutex());
|
||||
|
||||
// Close this pak file.
|
||||
if (!CloseLevelPack(m_levelPak, true))
|
||||
{
|
||||
Error("Cannot close Pak file " + m_levelPak.m_sPath);
|
||||
exportSuccessful = false;
|
||||
}
|
||||
|
||||
if (exportSuccessful)
|
||||
{
|
||||
if (m_bAutoExportMode)
|
||||
{
|
||||
// Remove read-only flags.
|
||||
CrySetFileAttributes(m_levelPak.m_sPath.toUtf8().data(), FILE_ATTRIBUTE_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (exportSuccessful)
|
||||
{
|
||||
if (!CFileUtil::OverwriteFile(m_levelPak.m_sPath))
|
||||
{
|
||||
Error("Cannot overwrite Pak file " + m_levelPak.m_sPath);
|
||||
exportSuccessful = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (exportSuccessful)
|
||||
{
|
||||
if (!OpenLevelPack(m_levelPak, false))
|
||||
{
|
||||
Error("Cannot open Pak file " + m_levelPak.m_sPath + " for writing.");
|
||||
exportSuccessful = false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Inform all objects that an export is about to begin
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
if (exportSuccessful)
|
||||
{
|
||||
GetIEditor()->GetObjectManager()->GetPhysicsManager()->PrepareForExport();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Export all data to the game
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
if (exportSuccessful)
|
||||
{
|
||||
ExportVisAreas(sLevelPath.toUtf8().data(), eExportEndian);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Exporting map setttings
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
ExportOcclusionMesh(sLevelPath.toUtf8().data());
|
||||
|
||||
//! Export Level data.
|
||||
CLogFile::WriteLine("Exporting LevelData.xml");
|
||||
ExportLevelData(sLevelPath);
|
||||
CLogFile::WriteLine("Exporting LevelData.xml done.");
|
||||
|
||||
ExportLevelInfo(sLevelPath);
|
||||
|
||||
ExportLevelLensFlares(sLevelPath);
|
||||
ExportLevelResourceList(sLevelPath);
|
||||
ExportLevelUsedResourceList(sLevelPath);
|
||||
ExportLevelShaderCache(sLevelPath);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// End Exporting Game data.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Close all packs.
|
||||
CloseLevelPack(m_levelPak, false);
|
||||
// m_texturePakFile.Close();
|
||||
|
||||
pEditor->SetStatusText(QObject::tr("Ready"));
|
||||
|
||||
// Reopen this pak file.
|
||||
if (!OpenLevelPack(m_levelPak, true))
|
||||
{
|
||||
Error("Cannot open Pak file " + m_levelPak.m_sPath);
|
||||
exportSuccessful = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (exportSuccessful)
|
||||
{
|
||||
// Commit changes to the disk.
|
||||
_flushall();
|
||||
|
||||
// finally create filelist.xml
|
||||
QString levelName = Path::GetFileName(pGameEngine->GetLevelPath());
|
||||
ExportFileList(sLevelPath, levelName);
|
||||
|
||||
pDocument->SetLevelExported(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Always notify that we've finished exporting, whether it was successful or not.
|
||||
pEditor->Notify(eNotify_OnExportToGame);
|
||||
CrySystemEventBus::Broadcast(&CrySystemEventBus::Events::OnCryEditorEndLevelExport, exportSuccessful);
|
||||
|
||||
if (exportSuccessful)
|
||||
{
|
||||
// Notify the level system that there's a new level, so that the level info is populated.
|
||||
gEnv->pSystem->GetILevelSystem()->Rescan("levels", ILevelSystem::TAG_MAIN);
|
||||
gEnv->pSystem->GetILevelSystem()->Rescan(ILevelSystem::GetLevelsDirectoryName());
|
||||
|
||||
CLogFile::WriteLine("Exporting was successful.");
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "Util/PakFile.h"
|
||||
#include "Util/Image.h"
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
|
||||
enum EGameExport
|
||||
{
|
||||
@@ -26,7 +27,6 @@ enum EGameExport
|
||||
};
|
||||
|
||||
|
||||
class CTerrainLightGen;
|
||||
class CWaitProgress;
|
||||
class CUsedResources;
|
||||
|
||||
@@ -61,21 +61,33 @@ class SANDBOX_API CGameExporter
|
||||
public:
|
||||
CGameExporter();
|
||||
~CGameExporter();
|
||||
static const char* GetLevelPakFilename() { return "level.pak"; }
|
||||
SGameExporterSettings& GetSettings() { return m_settings; }
|
||||
|
||||
SLevelPakHelper& GetLevelPack() { return m_levelPak; }
|
||||
|
||||
// In auto exporting mode, highest possible settings will be chosen and no UI dialogs will be shown.
|
||||
void SetAutoExportMode(bool bAuto) { m_bAutoExportMode = bAuto; }
|
||||
|
||||
bool Export(unsigned int flags = 0, EEndian eExportEndian = GetPlatformEndian(), const char* subdirectory = 0);
|
||||
|
||||
bool OpenLevelPack(SLevelPakHelper& lphelper, bool bCryPak = false);
|
||||
bool CloseLevelPack(SLevelPakHelper& lphelper, bool bCryPak = false);
|
||||
static CGameExporter* GetCurrentExporter() { return m_pCurrentExporter; }
|
||||
|
||||
private:
|
||||
bool OpenLevelPack(SLevelPakHelper& lphelper, bool bCryPak = false);
|
||||
bool CloseLevelPack(SLevelPakHelper& lphelper, bool bCryPak = false);
|
||||
|
||||
static const char* GetLevelPakFilename()
|
||||
{
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
if (usePrefabSystemForLevels)
|
||||
{
|
||||
AZ_Assert(false, "Level.pak should no longer be used when prefabs are used for levels.");
|
||||
return "";
|
||||
}
|
||||
|
||||
return "level.pak";
|
||||
}
|
||||
|
||||
void ExportLevelData(const QString& path, bool bExportMission = true);
|
||||
void ExportLevelInfo(const QString& path);
|
||||
|
||||
|
||||
@@ -144,8 +144,6 @@ enum EEditorNotifyEvent
|
||||
eNotify_OnMissionChange, // Send when the current mission changes.
|
||||
eNotify_OnBeginLoad, // Sent when the document is start to load.
|
||||
eNotify_OnEndLoad, // Sent when the document loading is finished
|
||||
eNotify_OnBeginExportToGame, // Sent when the level starts to be exported to game
|
||||
eNotify_OnExportToGame, // Sent when the level is exported to game
|
||||
|
||||
// Editing events.
|
||||
eNotify_OnEditModeChange, // Sent when editing mode change (move,rotate,scale,....)
|
||||
@@ -818,7 +816,6 @@ struct IEditor
|
||||
virtual void LoadPlugins() = 0;
|
||||
|
||||
virtual bool IsNewViewportInteractionModelEnabled() const = 0;
|
||||
virtual bool IsPrefabSystemEnabled() const = 0;
|
||||
};
|
||||
|
||||
//! Callback used by editor when initializing for info in UI dialogs
|
||||
|
||||
@@ -90,9 +90,6 @@ AZ_POP_DISABLE_WARNING
|
||||
|
||||
#include "Editor/AssetDatabase/AssetDatabaseLocationListener.h"
|
||||
#include "Editor/AzAssetBrowser/AzAssetBrowserRequestHandler.h"
|
||||
#include "Editor/Thumbnails/TextureThumbnailRenderer.h"
|
||||
#include "Editor/Thumbnails/StaticMeshThumbnailRenderer.h"
|
||||
#include "Editor/Thumbnails/MaterialThumbnailRenderer.h"
|
||||
#include "Editor/AssetEditor/AssetEditorRequestsHandler.h"
|
||||
|
||||
// EditorCommon
|
||||
@@ -213,9 +210,6 @@ CEditorImpl::CEditorImpl()
|
||||
SetPrimaryCDFolder();
|
||||
gSettings.Load();
|
||||
|
||||
// retrieve this after the settings have been loaded
|
||||
m_isPrefabSystemEnabled = gSettings.prefabSystem;
|
||||
|
||||
m_pErrorReport = new CErrorReport;
|
||||
m_pClassFactory = CClassFactory::Instance();
|
||||
m_pCommandManager = new CEditorCommandManager;
|
||||
@@ -451,10 +445,6 @@ void CEditorImpl::SetGameEngine(CGameEngine* ge)
|
||||
|
||||
m_pMaterialManager->Set3DEngine();
|
||||
m_pAnimationContext->Init();
|
||||
|
||||
m_thumbnailRenderers.push_back(AZStd::make_unique<TextureThumbnailRenderer>());
|
||||
m_thumbnailRenderers.push_back(AZStd::make_unique<StaticMeshThumbnailRenderer>());
|
||||
m_thumbnailRenderers.push_back(AZStd::make_unique<MaterialThumbnailRenderer>());
|
||||
}
|
||||
|
||||
void CEditorImpl::RegisterTools()
|
||||
@@ -2087,11 +2077,6 @@ bool CEditorImpl::IsNewViewportInteractionModelEnabled() const
|
||||
return m_isNewViewportInteractionModelEnabled;
|
||||
}
|
||||
|
||||
bool CEditorImpl::IsPrefabSystemEnabled() const
|
||||
{
|
||||
return m_isPrefabSystemEnabled;
|
||||
}
|
||||
|
||||
void CEditorImpl::OnStartPlayInEditor()
|
||||
{
|
||||
if (SelectionContainsComponentEntities())
|
||||
|
||||
@@ -360,7 +360,6 @@ public:
|
||||
void DestroyQMimeData(QMimeData* data) const override;
|
||||
|
||||
bool IsNewViewportInteractionModelEnabled() const override;
|
||||
bool IsPrefabSystemEnabled() const override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -469,7 +468,6 @@ protected:
|
||||
::AssetDatabase::AssetDatabaseLocationListener* m_pAssetDatabaseLocationListener;
|
||||
AzAssetBrowserRequestHandler* m_pAssetBrowserRequestHandler;
|
||||
AssetEditorRequestsHandler* m_assetEditorRequestsHandler;
|
||||
AZStd::vector<AZStd::unique_ptr<AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::Handler>> m_thumbnailRenderers;
|
||||
|
||||
IImageUtil* m_pImageUtil; // Vladimir@conffx
|
||||
ILogFile* m_pLogFile; // Vladimir@conffx
|
||||
@@ -478,6 +476,5 @@ protected:
|
||||
static const char* m_crashLogFileName;
|
||||
|
||||
bool m_isNewViewportInteractionModelEnabled = true;
|
||||
bool m_isPrefabSystemEnabled = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -768,12 +768,12 @@ QString CCommand6<LIST(6, P)>::Execute(const CCommand::CArgs& args)
|
||||
return "";
|
||||
}
|
||||
|
||||
P1 p1;
|
||||
P2 p2;
|
||||
P3 p3;
|
||||
P4 p4;
|
||||
P5 p5;
|
||||
P6 p6;
|
||||
P1 p1 = 0;
|
||||
P2 p2 = 0;
|
||||
P3 p3 = 0;
|
||||
P4 p4 = 0;
|
||||
P5 p5 = 0;
|
||||
P6 p6 = 0;
|
||||
bool ok = FromString_(p1, args.GetArg(0).c_str())
|
||||
&& FromString_(p2, args.GetArg(1).c_str())
|
||||
&& FromString_(p3, args.GetArg(2).c_str())
|
||||
@@ -782,9 +782,7 @@ QString CCommand6<LIST(6, P)>::Execute(const CCommand::CArgs& args)
|
||||
&& FromString_(p6, args.GetArg(5).c_str());
|
||||
if (ok)
|
||||
{
|
||||
AZ_PUSH_DISABLE_WARNING(4703, "-Wunknown-warning-option")
|
||||
m_functor(p1, p2, p3, p4, p5, p6);
|
||||
AZ_POP_DISABLE_WARNING
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -43,8 +43,6 @@ enum ObjectEvent
|
||||
EVENT_PHYSICS_RESETSTATE,//!< Signals that physics state must be reseted on objects.
|
||||
EVENT_PHYSICS_APPLYSTATE,//!< Signals that the stored physics state must be applied to objects.
|
||||
|
||||
EVENT_PRE_EXPORT, //!< Signals that the game is about to be exported, prepare any data if the object needs to
|
||||
|
||||
EVENT_FREE_GAME_DATA,//!< Object should free game data that its holding.
|
||||
EVENT_CONFIG_SPEC_CHANGE, //!< Called when config spec changed.
|
||||
EVENT_HIDE_HELPER, //!< Signals that happens when Helper mode switches to be hidden.
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
#include "LevelFileDialog.h"
|
||||
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
|
||||
// Qt
|
||||
#include <QMessageBox>
|
||||
#include <QInputDialog>
|
||||
@@ -22,6 +24,7 @@
|
||||
// Editor
|
||||
#include "LevelTreeModel.h"
|
||||
#include "CryEditDoc.h"
|
||||
#include "API/ToolsApplicationAPI.h"
|
||||
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
@@ -30,10 +33,6 @@ AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
static const char lastLoadPathFilename[] = "lastLoadPath.preset";
|
||||
|
||||
// File name extension for the main level file
|
||||
static const char kLevelExtension[] = "ly";
|
||||
static const char kOldLevelExtension[] = "cry";
|
||||
|
||||
// Folder in which levels are stored
|
||||
static const char kLevelsFolder[] = "Levels";
|
||||
|
||||
@@ -49,10 +48,8 @@ static const char* kLevelFolderNames[] =
|
||||
static const char* kLevelFileNames[] =
|
||||
{
|
||||
"level.pak",
|
||||
"terraintexture.pak",
|
||||
"filelist.xml",
|
||||
"levelshadercache.pak",
|
||||
"terrain\\cover.ctc"
|
||||
};
|
||||
|
||||
CLevelFileDialog::CLevelFileDialog(bool openDialog, QWidget* parent)
|
||||
@@ -164,7 +161,7 @@ void CLevelFileDialog::OnOK()
|
||||
}
|
||||
}
|
||||
|
||||
m_fileName = levelPath + "/" + Path::GetFileName(levelPath) + "." + kLevelExtension;
|
||||
m_fileName = levelPath + "/" + Path::GetFileName(levelPath) + EditorUtils::LevelFile::GetDefaultFileExtension();
|
||||
}
|
||||
|
||||
SaveLastUsedLevelPath();
|
||||
@@ -209,9 +206,12 @@ bool CLevelFileDialog::IsValidLevelSelected()
|
||||
QString levelPath = GetLevelPath();
|
||||
m_fileName = GetFileName(levelPath);
|
||||
|
||||
QString currentExtension = Path::GetExt(m_fileName);
|
||||
QString currentExtension = "." + Path::GetExt(m_fileName);
|
||||
|
||||
bool isInvalidFileExtension = (currentExtension != kLevelExtension && currentExtension != kOldLevelExtension);
|
||||
const char* oldExtension = EditorUtils::LevelFile::GetOldCryFileExtension();
|
||||
const char* defaultExtension = EditorUtils::LevelFile::GetDefaultFileExtension();
|
||||
|
||||
bool isInvalidFileExtension = (currentExtension != defaultExtension && currentExtension != oldExtension);
|
||||
|
||||
if (!isInvalidFileExtension && CFileUtil::FileExists(m_fileName))
|
||||
{
|
||||
@@ -246,10 +246,13 @@ QString CLevelFileDialog::GetFileName(QString levelPath)
|
||||
|
||||
if (CheckLevelFolder(levelPath, &levelFiles) && levelFiles.size() >= 1)
|
||||
{
|
||||
const char* oldExtension = EditorUtils::LevelFile::GetOldCryFileExtension();
|
||||
const char* defaultExtension = EditorUtils::LevelFile::GetDefaultFileExtension();
|
||||
|
||||
// A level folder was entered. Prefer the .ly/.cry file with the
|
||||
// folder name, otherwise pick the first one in the list
|
||||
QString path = Path::GetFileName(levelPath);
|
||||
QString needle = path + "." + kLevelExtension;
|
||||
QString needle = path + defaultExtension;
|
||||
auto iter = std::find(levelFiles.begin(), levelFiles.end(), needle);
|
||||
|
||||
if (iter != levelFiles.end())
|
||||
@@ -258,7 +261,7 @@ QString CLevelFileDialog::GetFileName(QString levelPath)
|
||||
}
|
||||
else
|
||||
{
|
||||
needle = path + "." + kOldLevelExtension;
|
||||
needle = path + oldExtension;
|
||||
iter = std::find(levelFiles.begin(), levelFiles.end(), needle);
|
||||
if (iter != levelFiles.end())
|
||||
{
|
||||
@@ -379,7 +382,7 @@ void CLevelFileDialog::ReloadTree()
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Heuristic to detect a level folder, also returns all .cry files in it
|
||||
// Heuristic to detect a level folder, also returns all .cry/.ly files in it
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CLevelFileDialog::CheckLevelFolder(const QString folder, QStringList* levelFiles)
|
||||
{
|
||||
@@ -392,28 +395,13 @@ bool CLevelFileDialog::CheckLevelFolder(const QString folder, QStringList* level
|
||||
{
|
||||
const QString fileName = fileData.fileName();
|
||||
|
||||
// Have we found a folder?
|
||||
if (fileData.isDir())
|
||||
if (!fileData.isDir())
|
||||
{
|
||||
// Skip the parent folder entries
|
||||
if (fileName == "." || fileName == "..")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QString ext = "." + Path::GetExt(fileName);
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(kLevelFolderNames) / sizeof(char*); ++i)
|
||||
{
|
||||
if (fileName == kLevelFolderNames[i])
|
||||
{
|
||||
bIsLevelFolder = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QString ext = Path::GetExt(fileName);
|
||||
const char* defaultExtension = EditorUtils::LevelFile::GetDefaultFileExtension();
|
||||
|
||||
if (ext == kLevelExtension || ext == kOldLevelExtension)
|
||||
if (ext == defaultExtension)
|
||||
{
|
||||
bIsLevelFolder = true;
|
||||
|
||||
@@ -422,14 +410,6 @@ bool CLevelFileDialog::CheckLevelFolder(const QString folder, QStringList* level
|
||||
levelFiles->push_back(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(kLevelFileNames) / sizeof(char*); ++i)
|
||||
{
|
||||
if (fileName == kLevelFileNames[i])
|
||||
{
|
||||
bIsLevelFolder = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,8 @@ void LevelTreeModel::ReloadTree(QStandardItem* root, bool recurseIfNoLevels)
|
||||
QDir currentDir(parentFullPath);
|
||||
currentDir.setFilter(QDir::NoDot | QDir::NoDotDot | QDir::Dirs);
|
||||
const QStringList subFolders = currentDir.entryList();
|
||||
foreach (const QString &subFolder, subFolders) {
|
||||
foreach (const QString &subFolder, subFolders)
|
||||
{
|
||||
auto child = new QStandardItem(subFolder);
|
||||
child->setData(parentFullPath + "/" + subFolder, FullPathRole);
|
||||
child->setEditable(false);
|
||||
|
||||
@@ -211,7 +211,6 @@ public:
|
||||
MOCK_METHOD0(UnloadPlugins, void());
|
||||
MOCK_METHOD0(LoadPlugins, void());
|
||||
MOCK_CONST_METHOD0(IsNewViewportInteractionModelEnabled, bool());
|
||||
MOCK_CONST_METHOD0(IsPrefabSystemEnabled, bool());
|
||||
MOCK_METHOD1(GetSearchPath, QString(EEditorPathName));
|
||||
MOCK_METHOD0(GetEditorPanelUtils, IEditorPanelUtils* ());
|
||||
|
||||
|
||||
@@ -812,9 +812,17 @@ void MainWindow::InitActions()
|
||||
.SetStatusTip(tr("Save Resources"))
|
||||
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateDocumentReady);
|
||||
am->AddAction(ID_IMPORT_ASSET, tr("Import &FBX..."));
|
||||
am->AddAction(ID_FILE_EXPORTTOGAMENOSURFACETEXTURE, tr("&Export to Engine"))
|
||||
.SetShortcut(tr("Ctrl+E"))
|
||||
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateDocumentReady);
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
if (!usePrefabSystemForLevels)
|
||||
{
|
||||
am->AddAction(ID_FILE_EXPORTTOGAMENOSURFACETEXTURE, tr("&Export to Engine"))
|
||||
.SetShortcut(tr("Ctrl+E"))
|
||||
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateDocumentReady);
|
||||
}
|
||||
|
||||
am->AddAction(ID_FILE_EXPORT_SELECTEDOBJECTS, tr("Export Selected &Objects"))
|
||||
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateSelected);
|
||||
am->AddAction(ID_FILE_EXPORTOCCLUSIONMESH, tr("Export Occlusion Mesh"));
|
||||
@@ -980,10 +988,20 @@ void MainWindow::InitActions()
|
||||
.SetShortcut(QKeySequence::Delete)
|
||||
.SetStatusTip(tr("Delete selected objects."))
|
||||
->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
||||
am->AddAction(ID_EDIT_CLONE, tr("Duplicate"))
|
||||
.SetShortcut(tr("Ctrl+D"))
|
||||
.SetToolTip(tr("Duplicate (Ctrl+D)"))
|
||||
.SetStatusTip(tr("Duplicate selected objects."));
|
||||
|
||||
bool isPrefabSystemEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(isPrefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
bool prefabWipFeaturesEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(prefabWipFeaturesEnabled, &AzFramework::ApplicationRequests::ArePrefabWipFeaturesEnabled);
|
||||
|
||||
if (!isPrefabSystemEnabled || (isPrefabSystemEnabled && prefabWipFeaturesEnabled))
|
||||
{
|
||||
am->AddAction(ID_EDIT_CLONE, tr("Duplicate"))
|
||||
.SetShortcut(tr("Ctrl+D"))
|
||||
.SetToolTip(tr("Duplicate (Ctrl+D)"))
|
||||
.SetStatusTip(tr("Duplicate selected objects."));
|
||||
}
|
||||
}
|
||||
|
||||
// Modify actions
|
||||
@@ -1091,7 +1109,7 @@ void MainWindow::InitActions()
|
||||
.SetApplyHoverEffect();
|
||||
am->AddAction(ID_OBJECTMODIFY_ALIGN, tr("Align to object")).SetCheckable(true)
|
||||
#if AZ_TRAIT_OS_PLATFORM_APPLE
|
||||
.SetStatusTip(tr("⌘: Align an object to a bounding box, ⌥ : Keep Rotation of the moved object, Shift : Keep Scale of the moved object"))
|
||||
.SetStatusTip(tr(u8"\u2318: Align an object to a bounding box, \u2325 : Keep Rotation of the moved object, Shift : Keep Scale of the moved object"))
|
||||
#else
|
||||
.SetStatusTip(tr("Ctrl: Align an object to a bounding box, Alt : Keep Rotation of the moved object, Shift : Keep Scale of the moved object"))
|
||||
#endif
|
||||
|
||||
@@ -304,10 +304,10 @@ private:
|
||||
int m_propagationFlags;
|
||||
|
||||
//! Material Used in level.
|
||||
int m_bDummyMaterial : 1; // Dummy material, name specified but material file not found.
|
||||
int m_bIgnoreNotifyChange : 1; // Do not send notifications about changes.
|
||||
int m_bRegetPublicParams : 1;
|
||||
int m_bKeepPublicParamsValues : 1;
|
||||
unsigned int m_bDummyMaterial : 1; // Dummy material, name specified but material file not found.
|
||||
unsigned int m_bIgnoreNotifyChange : 1; // Do not send notifications about changes.
|
||||
unsigned int m_bRegetPublicParams : 1;
|
||||
unsigned int m_bKeepPublicParamsValues : 1;
|
||||
|
||||
bool m_allowLayerActivation;
|
||||
};
|
||||
|
||||
@@ -51,10 +51,6 @@ CMission::CMission(CCryEditDoc* doc)
|
||||
|
||||
m_numCGFObjects = 0;
|
||||
|
||||
m_minimap.vCenter = Vec2(512, 512);
|
||||
m_minimap.vExtends = Vec2(512, 512);
|
||||
m_minimap.textureWidth = m_minimap.textureHeight = 1024;
|
||||
|
||||
m_reentrancyProtector = false;
|
||||
}
|
||||
|
||||
@@ -85,10 +81,6 @@ void CMission::Serialize(CXmlArchive& ar, bool bParts)
|
||||
ar.root->getAttr("Name", m_name);
|
||||
ar.root->getAttr("Description", m_description);
|
||||
|
||||
//time_t time = 0;
|
||||
//ar.root->getAttr( "Time",time );
|
||||
//m_time = time;
|
||||
|
||||
XmlNodeRef objects = ar.root->findChild("Objects");
|
||||
if (objects)
|
||||
{
|
||||
@@ -105,35 +97,13 @@ void CMission::Serialize(CXmlArchive& ar, bool bParts)
|
||||
|
||||
m_Animations = ar.root->findChild("MovieData");
|
||||
|
||||
/*
|
||||
XmlNodeRef expData = ar.root->findChild( "ExportData" );
|
||||
if (expData)
|
||||
{
|
||||
m_exportData = expData;
|
||||
}
|
||||
*/
|
||||
SerializeEnvironment(ar);
|
||||
|
||||
XmlNodeRef minimapNode = ar.root->findChild("MiniMap");
|
||||
if (minimapNode)
|
||||
{
|
||||
minimapNode->getAttr("CenterX", m_minimap.vCenter.x);
|
||||
minimapNode->getAttr("CenterY", m_minimap.vCenter.y);
|
||||
minimapNode->getAttr("ExtendsX", m_minimap.vExtends.x);
|
||||
minimapNode->getAttr("ExtendsY", m_minimap.vExtends.y);
|
||||
// minimapNode->getAttr( "CameraHeight",m_minimap.cameraHeight );
|
||||
minimapNode->getAttr("TexWidth", m_minimap.textureWidth);
|
||||
minimapNode->getAttr("TexHeight", m_minimap.textureHeight);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ar.root->setAttr("Name", m_name.toUtf8().data());
|
||||
ar.root->setAttr("Description", m_description.toUtf8().data());
|
||||
|
||||
//time_t time = m_time.GetTime();
|
||||
//ar.root->setAttr( "Time",time );
|
||||
|
||||
QString timeStr;
|
||||
int nHour = floor(m_time);
|
||||
int nMins = (m_time - floor(m_time)) * 60.0f;
|
||||
@@ -154,15 +124,6 @@ void CMission::Serialize(CXmlArchive& ar, bool bParts)
|
||||
SerializeTimeOfDay(ar);
|
||||
SerializeEnvironment(ar);
|
||||
}
|
||||
|
||||
XmlNodeRef minimapNode = ar.root->newChild("MiniMap");
|
||||
minimapNode->setAttr("CenterX", m_minimap.vCenter.x);
|
||||
minimapNode->setAttr("CenterY", m_minimap.vCenter.y);
|
||||
minimapNode->setAttr("ExtendsX", m_minimap.vExtends.x);
|
||||
minimapNode->setAttr("ExtendsY", m_minimap.vExtends.y);
|
||||
// minimapNode->setAttr( "CameraHeight",m_minimap.cameraHeight );
|
||||
minimapNode->setAttr("TexWidth", m_minimap.textureWidth);
|
||||
minimapNode->setAttr("TexHeight", m_minimap.textureHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,15 +151,6 @@ void CMission::Export(XmlNodeRef& root, XmlNodeRef& objectsNode)
|
||||
m_timeOfDay->setAttr("Time", m_time);
|
||||
root->addChild(m_timeOfDay);
|
||||
|
||||
XmlNodeRef minimapNode = root->newChild("MiniMap");
|
||||
minimapNode->setAttr("CenterX", m_minimap.vCenter.x);
|
||||
minimapNode->setAttr("CenterY", m_minimap.vCenter.y);
|
||||
minimapNode->setAttr("ExtendsX", m_minimap.vExtends.x);
|
||||
minimapNode->setAttr("ExtendsY", m_minimap.vExtends.y);
|
||||
// minimapNode->setAttr( "CameraHeight",m_minimap.cameraHeight );
|
||||
minimapNode->setAttr("TexWidth", m_minimap.textureWidth);
|
||||
minimapNode->setAttr("TexHeight", m_minimap.textureHeight);
|
||||
|
||||
IObjectManager* pObjMan = GetIEditor()->GetObjectManager();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -211,19 +163,6 @@ void CMission::Export(XmlNodeRef& root, XmlNodeRef& objectsNode)
|
||||
objectsNode = root->newChild("Objects");
|
||||
pObjMan->Export(path, objectsNode, true); // Export shared.
|
||||
pObjMan->Export(path, objectsNode, false); // Export not shared.
|
||||
|
||||
/*
|
||||
CObjectManager objectManager;
|
||||
XmlNodeRef loadRoot = root->createNode("Root");
|
||||
loadRoot->addChild( m_objects );
|
||||
|
||||
std::vector<CObjectClassDesc*> classes;
|
||||
GetIEditor()->GetObjectManager()->GetClasses( classes );
|
||||
objectManager.SetClasses( classes );
|
||||
objectManager.SetCreateGameObject(false);
|
||||
objectManager.Serialize( loadRoot,true,SERIALIZE_ALL );
|
||||
objectManager.Export( path,objects,false );
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -321,13 +260,6 @@ void CMission::SetLayersNode(XmlNodeRef& node)
|
||||
m_layers = node->clone();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CMission::SetMinimap(const SMinimapInfo& minimap)
|
||||
{
|
||||
m_minimap = minimap;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CMission::SaveParts()
|
||||
{
|
||||
@@ -427,9 +359,3 @@ void CMission::SerializeEnvironment(CXmlArchive& ar)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
const SMinimapInfo& CMission::GetMinimap() const
|
||||
{
|
||||
return m_minimap;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,16 +16,6 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
struct SMinimapInfo
|
||||
{
|
||||
Vec2 vCenter;
|
||||
Vec2 vExtends;
|
||||
// float RenderBoxSize;
|
||||
int textureWidth;
|
||||
int textureHeight;
|
||||
int orientation;
|
||||
};
|
||||
|
||||
/*!
|
||||
CMission represent single Game Mission on same map.
|
||||
Multiple Missions share same map, and stored in one .cry or .ly file.
|
||||
@@ -82,11 +72,6 @@ public:
|
||||
void OnEnvironmentChange();
|
||||
int GetNumCGFObjects() const { return m_numCGFObjects; };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Minimap.
|
||||
void SetMinimap(const SMinimapInfo& info);
|
||||
const SMinimapInfo& GetMinimap() const;
|
||||
|
||||
private:
|
||||
//! Document owner of this mission.
|
||||
CCryEditDoc* m_doc;
|
||||
@@ -115,8 +100,6 @@ private:
|
||||
|
||||
int m_numCGFObjects;
|
||||
|
||||
SMinimapInfo m_minimap;
|
||||
|
||||
bool m_reentrancyProtector;
|
||||
};
|
||||
|
||||
|
||||
@@ -64,6 +64,8 @@ void CQuickAccessBar::OnInitDialog()
|
||||
// Make this window 50% alpha.
|
||||
setWindowOpacity(0.5);
|
||||
|
||||
m_levelExtension = EditorUtils::LevelFile::GetDefaultFileExtension();
|
||||
|
||||
CollectMenuItems(MainWindow::instance()->menuBar());
|
||||
|
||||
AddMRUFileItems();
|
||||
@@ -143,7 +145,7 @@ void CQuickAccessBar::AddMRUFileItems()
|
||||
{
|
||||
QString mruText;
|
||||
pMRUList->GetDisplayName(mruText, i, "");
|
||||
if (mruText.isEmpty())
|
||||
if (mruText.isEmpty() || !(*pMRUList)[i].endsWith(m_levelExtension))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ private:
|
||||
QStringListModel* m_model;
|
||||
|
||||
QScopedPointer<Ui::QuickAccessBar> m_ui;
|
||||
const char* m_levelExtension = nullptr;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_QUICKACCESSBAR_H
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
#include <QtGui/private/qhighdpiscaling_p.h>
|
||||
|
||||
AZ_CVAR(
|
||||
bool, ed_visibility_use, false, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
bool, ed_visibility_use, true, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
"Enable/disable using the new IVisibilitySystem for Entity visibility determination");
|
||||
AZ_CVAR(
|
||||
bool, ed_visibility_logTiming, false, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
// AzFramework
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/SourceControl/SourceControlAPI.h>
|
||||
|
||||
@@ -34,9 +37,6 @@
|
||||
#include "CryEdit.h"
|
||||
#include "MainWindow.h"
|
||||
|
||||
// Editor Preferences Settings Registry keys
|
||||
constexpr char prefabSystemKey[] = "/Amazon/Editor/Preferences/EnablePrefabSystem";
|
||||
|
||||
#pragma comment(lib, "Gdi32.lib")
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -694,7 +694,8 @@ void SEditorSettings::Save()
|
||||
// --- Settings Registry values
|
||||
|
||||
// Prefab System UI
|
||||
SetSettingsRegistry_Bool(prefabSystemKey, prefabSystem);
|
||||
AzFramework::ApplicationRequests::Bus::Broadcast(
|
||||
&AzFramework::ApplicationRequests::SetPrefabSystemEnabled, prefabSystem);
|
||||
|
||||
SaveSettingsRegistryFile();
|
||||
}
|
||||
@@ -943,7 +944,9 @@ void SEditorSettings::Load()
|
||||
}
|
||||
|
||||
// Load from Settings Registry
|
||||
GetSettingsRegistry_Bool(prefabSystemKey, prefabSystem);
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
prefabSystem, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -1178,11 +1181,11 @@ void SEditorSettings::SaveSettingsRegistryFile()
|
||||
|
||||
AZ::SettingsRegistryMergeUtils::DumperSettings dumperSettings;
|
||||
dumperSettings.m_prettifyOutput = true;
|
||||
dumperSettings.m_jsonPointerPrefix = "/Amazon/Editor/Preferences";
|
||||
dumperSettings.m_jsonPointerPrefix = "/Amazon/Preferences";
|
||||
|
||||
AZStd::string stringBuffer;
|
||||
AZ::IO::ByteContainerStream stringStream(&stringBuffer);
|
||||
if (!AZ::SettingsRegistryMergeUtils::DumpSettingsRegistryToStream(*registry, "/Amazon/Editor/Preferences", stringStream, dumperSettings))
|
||||
if (!AZ::SettingsRegistryMergeUtils::DumpSettingsRegistryToStream(*registry, "/Amazon/Preferences", stringStream, dumperSettings))
|
||||
{
|
||||
AZ_Warning("SEditorSettings", false, R"(Unable to save changes to the Editor Preferences registry file at "%s"\n)",
|
||||
editorPreferencesFilePath.c_str());
|
||||
|
||||
@@ -499,7 +499,7 @@ AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
|
||||
|
||||
SSliceSettings sliceSettings;
|
||||
|
||||
bool prefabSystem = false; ///< Toggle to enable the Prefab system for level entities.
|
||||
bool prefabSystem = true; ///< Toggle to enable/disable the Prefab system for level entities.
|
||||
|
||||
private:
|
||||
void SaveValue(const char* sSection, const char* sKey, int value);
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* 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 "ThumbnailsSampleWidget.h"
|
||||
|
||||
// Qt
|
||||
#include <QLabel>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserModel.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailWidget.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Thumbnails/AssetBrowserProductThumbnail.h>
|
||||
|
||||
// Editor
|
||||
#include "QtViewPaneManager.h" // for RegisterQtViewPane
|
||||
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#include <Thumbnails/Example/ui_ThumbnailsSampleWidget.h>
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
const int MAX_PRODUCTS_TO_DISPLAY = 20;
|
||||
|
||||
ThumbnailsSampleWidget::ThumbnailsSampleWidget(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::ThumbnailsSampleWidgetClass())
|
||||
, m_filterModel(new AzToolsFramework::AssetBrowser::AssetBrowserFilterModel(parent))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->m_searchWidget->Setup(true, true);
|
||||
|
||||
using namespace AzToolsFramework::AssetBrowser;
|
||||
AssetBrowserComponentRequestBus::BroadcastResult(m_assetBrowserModel, &AssetBrowserComponentRequests::GetAssetBrowserModel);
|
||||
AZ_Assert(m_assetBrowserModel, "Failed to get filebrowser model");
|
||||
m_filterModel->setSourceModel(m_assetBrowserModel);
|
||||
m_filterModel->SetFilter(m_ui->m_searchWidget->GetFilter());
|
||||
|
||||
m_ui->m_assetBrowserTreeViewWidget->setModel(m_filterModel.data());
|
||||
|
||||
auto layout = static_cast<QVBoxLayout*>(m_ui->m_thumbnailScrollAreaRoot->layout());
|
||||
layout->addStretch(1);
|
||||
|
||||
connect(m_ui->m_assetBrowserTreeViewWidget, &AssetBrowserTreeView::selectionChangedSignal,
|
||||
this, &ThumbnailsSampleWidget::SelectionChangedSlot);
|
||||
connect(m_ui->m_searchWidget->GetFilter().data(), &AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter::updatedSignal,
|
||||
m_filterModel.data(), &AzToolsFramework::AssetBrowser::AssetBrowserFilterModel::filterUpdatedSlot);
|
||||
}
|
||||
|
||||
ThumbnailsSampleWidget::~ThumbnailsSampleWidget() = default;
|
||||
|
||||
void ThumbnailsSampleWidget::RegisterViewClass()
|
||||
{
|
||||
QtViewOptions options;
|
||||
options.preferedDockingArea = Qt::NoDockWidgetArea;
|
||||
options.canHaveMultipleInstances = true;
|
||||
RegisterQtViewPane<ThumbnailsSampleWidget>(GetIEditor(), "Thumbnails Demo", LyViewPane::CategoryTools, options);
|
||||
}
|
||||
|
||||
void ThumbnailsSampleWidget::SelectionChangedSlot(const QItemSelection& /*selected*/, const QItemSelection& /*deselected*/) const
|
||||
{
|
||||
UpdateThumbnail();
|
||||
}
|
||||
|
||||
void ThumbnailsSampleWidget::UpdateThumbnail() const
|
||||
{
|
||||
auto layout = static_cast<QVBoxLayout*>(m_ui->m_thumbnailScrollAreaRoot->layout());
|
||||
// delete any previous thumbnails
|
||||
qDeleteAll(m_ui->m_thumbnailScrollAreaRoot->findChildren<QWidget*>("", Qt::FindDirectChildrenOnly));
|
||||
|
||||
auto selectedAssets = m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets();
|
||||
if (selectedAssets.size() > 0)
|
||||
{
|
||||
using namespace AzToolsFramework::AssetBrowser;
|
||||
//get all products from selected entry (it can be a folder, source or product asset and can contain 0 or more products)
|
||||
AZStd::vector<const ProductAssetBrowserEntry*> products;
|
||||
selectedAssets.front()->GetChildrenRecursively<ProductAssetBrowserEntry>(products);
|
||||
|
||||
// because thumbnails are displayed via individual widgets, limit to 10 otherwise it can take ages
|
||||
|
||||
int productsLeft = MAX_PRODUCTS_TO_DISPLAY;
|
||||
for (const auto* product : products)
|
||||
{
|
||||
// create thumbnail widget
|
||||
auto thumbnailWidget = new AzToolsFramework::Thumbnailer::ThumbnailWidget(m_ui->m_thumbnailScrollArea);
|
||||
thumbnailWidget->SetThumbnailKey(MAKE_TKEY(AzToolsFramework::AssetBrowser::ProductThumbnailKey, product->GetAssetId()));
|
||||
thumbnailWidget->setMinimumSize(100, 100);
|
||||
thumbnailWidget->setMaximumSize(100, 100);
|
||||
// insert it before space to align on top
|
||||
layout->insertWidget(layout->count() - 1, thumbnailWidget);
|
||||
// add label indicating name of the asset
|
||||
auto label = new QLabel(product->GetName().c_str(), m_ui->m_thumbnailScrollArea);
|
||||
layout->insertWidget(layout->count() - 1, label);
|
||||
// do not render more than 10 thumbnails at a time
|
||||
productsLeft--;
|
||||
if (productsLeft <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
#include <Thumbnails/Example/moc_ThumbnailsSampleWidget.cpp>
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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 <Editor/Util/FileUtil.h>
|
||||
#include <Editor/Util/Image.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QScopedPointer>
|
||||
#endif
|
||||
|
||||
class QItemSelection;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ThumbnailsSampleWidgetClass;
|
||||
}
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace AssetBrowser
|
||||
{
|
||||
class ProductAssetBrowserEntry;
|
||||
class AssetBrowserEntry;
|
||||
class AssetBrowserFilterModel;
|
||||
class AssetBrowserModel;
|
||||
}
|
||||
}
|
||||
|
||||
class ThumbnailsSampleWidget
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(ThumbnailsSampleWidget, AZ::SystemAllocator, 0);
|
||||
|
||||
explicit ThumbnailsSampleWidget(QWidget* parent = nullptr);
|
||||
~ThumbnailsSampleWidget() override;
|
||||
|
||||
static void RegisterViewClass();
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::ThumbnailsSampleWidgetClass> m_ui;
|
||||
QScopedPointer<AzToolsFramework::AssetBrowser::AssetBrowserFilterModel> m_filterModel;
|
||||
AzToolsFramework::AssetBrowser::AssetBrowserModel* m_assetBrowserModel;
|
||||
|
||||
void UpdateThumbnail() const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void SelectionChangedSlot(const QItemSelection& selected, const QItemSelection& deselected) const;
|
||||
};
|
||||
@@ -1,101 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ThumbnailsSampleWidgetClass</class>
|
||||
<widget class="QWidget" name="ThumbnailsSampleWidgetClass">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>567</width>
|
||||
<height>513</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Thumbnails Sample</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="AzToolsFramework::AssetBrowser::SearchWidget" name="m_searchWidget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="AzToolsFramework::AssetBrowser::AssetBrowserTreeView" name="m_assetBrowserTreeViewWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::DragOnly</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="m_thumbnailScrollArea">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="m_thumbnailScrollAreaRoot">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>181</width>
|
||||
<height>493</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout"/>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>AzToolsFramework::AssetBrowser::AssetBrowserTreeView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>AzToolsFramework::AssetBrowser::SearchWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>AzToolsFramework/AssetBrowser/Search/SearchWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,128 +0,0 @@
|
||||
/*
|
||||
* 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 "MaterialThumbnailRenderer.h"
|
||||
|
||||
// AzCore
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <AzCore/Asset/AssetTypeInfoBus.h>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/AssetBrowser/EBusFindAssetTypeByName.h>
|
||||
|
||||
// CryCommon
|
||||
#include <CryCommon/IStreamEngine.h>
|
||||
|
||||
// Editor
|
||||
#include "Util/Image.h"
|
||||
#include "Controls/PreviewModelCtrl.h"
|
||||
#include "Material/MaterialManager.h"
|
||||
|
||||
|
||||
const char* MATERIAL_PREVIEW_MODEL_FILE = "Editor/Objects/MtlSphere.cgf";
|
||||
|
||||
MaterialThumbnailRenderer::MaterialThumbnailRenderer()
|
||||
{
|
||||
m_previewControl = AZStd::make_unique<CPreviewModelCtrl>();
|
||||
m_previewControl->SetGrid(false);
|
||||
m_previewControl->SetAxis(false);
|
||||
m_previewControl->SetClearColor(ColorF(0, 0, 0, 0));
|
||||
|
||||
EBusFindAssetTypeByName result("Material");
|
||||
AZ::AssetTypeInfoBus::BroadcastResult(result, &AZ::AssetTypeInfo::GetAssetType);
|
||||
m_assetType = result.GetAssetType();
|
||||
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::Handler::BusConnect(m_assetType);
|
||||
AZ::SystemTickBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
MaterialThumbnailRenderer::~MaterialThumbnailRenderer()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::Handler::BusDisconnect();
|
||||
AZ::SystemTickBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void MaterialThumbnailRenderer::OnSystemTick()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::ExecuteQueuedEvents();
|
||||
}
|
||||
|
||||
void MaterialThumbnailRenderer::RenderThumbnail(AZ::Data::AssetId assetId, int thumbnailSize)
|
||||
{
|
||||
m_previewControl->setFixedSize(thumbnailSize, thumbnailSize);
|
||||
|
||||
// get asset type name
|
||||
AZ::Data::AssetInfo info;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(info, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, assetId);
|
||||
AZ::Data::AssetType assetType = info.m_assetType;
|
||||
QString assetTypeName;
|
||||
AZ::AssetTypeInfoBus::EventResult(assetTypeName, assetType, &AZ::AssetTypeInfo::GetAssetTypeDisplayName);
|
||||
|
||||
QPixmap thumbnail;
|
||||
|
||||
if (Render(thumbnail, assetId, thumbnailSize))
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(assetId,
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailRendered, thumbnail);
|
||||
}
|
||||
else
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(assetId,
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender);
|
||||
}
|
||||
}
|
||||
|
||||
bool MaterialThumbnailRenderer::Installed() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MaterialThumbnailRenderer::Render(QPixmap& thumbnail, AZ::Data::AssetId assetId, int thumbnailSize) const
|
||||
{
|
||||
// get filepath
|
||||
AZStd::string path;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
path,
|
||||
&AZ::Data::AssetCatalogRequests::GetAssetPathById,
|
||||
assetId);
|
||||
|
||||
auto material = GetIEditor()->GetMaterialManager()->LoadMaterial(path.c_str(), false);
|
||||
m_previewControl->LoadFile(MATERIAL_PREVIEW_MODEL_FILE);
|
||||
m_previewControl->SetMaterial(material);
|
||||
m_previewControl->FitToScreen();
|
||||
|
||||
gEnv->p3DEngine->Update();
|
||||
gEnv->pSystem->GetStreamEngine()->Update();
|
||||
|
||||
m_previewControl->Update(true);
|
||||
m_previewControl->repaint();
|
||||
CImageEx img;
|
||||
m_previewControl->show();
|
||||
// ensure all the initial (might be first time show) event handling is done for m_previewControl
|
||||
QCoreApplication::sendPostedEvents(m_previewControl.get());
|
||||
m_previewControl->GetImageOffscreen(img, QSize(thumbnailSize, thumbnailSize));
|
||||
m_previewControl->hide();
|
||||
|
||||
if (img.IsValid())
|
||||
{
|
||||
// this can fail if the request to draw the thumbnail was queued up but then the window
|
||||
// was hidden or deleted in the interim.
|
||||
thumbnail = QPixmap::fromImage(QImage(reinterpret_cast<uchar*>(img.GetData()),
|
||||
img.GetWidth(), img.GetHeight(), QImage::Format_ARGB32)).copy();
|
||||
img.Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* 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 <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
|
||||
class CPreviewModelCtrl;
|
||||
|
||||
//! Loads thumbnails that require acccess to renderer
|
||||
class MaterialThumbnailRenderer
|
||||
: public AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::Handler
|
||||
, public AZ::SystemTickBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(MaterialThumbnailRenderer, AZ::SystemAllocator, 0)
|
||||
|
||||
MaterialThumbnailRenderer();
|
||||
~MaterialThumbnailRenderer();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TickBus
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void OnSystemTick() override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ThumbnailerRendererRequests
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void RenderThumbnail(AZ::Data::AssetId assetId, int thumbnailSize) override;
|
||||
bool Installed() const override;
|
||||
|
||||
private:
|
||||
AZ::Data::AssetType m_assetType;
|
||||
AZStd::unique_ptr<CPreviewModelCtrl> m_previewControl;
|
||||
|
||||
bool Render(QPixmap& thumbnail, AZ::Data::AssetId assetId, int thumbnailSize) const;
|
||||
};
|
||||
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
* 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 "StaticMeshThumbnailRenderer.h"
|
||||
|
||||
// AzCore
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/AssetBrowser/EBusFindAssetTypeByName.h>
|
||||
|
||||
// CryCommon
|
||||
#include <CryCommon/IStreamEngine.h>
|
||||
|
||||
// Editor
|
||||
#include "Controls/PreviewModelCtrl.h"
|
||||
#include "Util/Image.h"
|
||||
|
||||
|
||||
StaticMeshThumbnailRenderer::StaticMeshThumbnailRenderer()
|
||||
{
|
||||
m_previewControl = AZStd::make_unique<CPreviewModelCtrl>();
|
||||
m_previewControl->SetGrid(false);
|
||||
m_previewControl->SetAxis(false);
|
||||
m_previewControl->SetClearColor(ColorF(0, 0, 0, 0));
|
||||
|
||||
EBusFindAssetTypeByName result("Static Mesh");
|
||||
AZ::AssetTypeInfoBus::BroadcastResult(result, &AZ::AssetTypeInfo::GetAssetType);
|
||||
m_assetType = result.GetAssetType();
|
||||
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::Handler::BusConnect(m_assetType);
|
||||
AZ::SystemTickBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
StaticMeshThumbnailRenderer::~StaticMeshThumbnailRenderer()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::Handler::BusDisconnect();
|
||||
AZ::SystemTickBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void StaticMeshThumbnailRenderer::OnSystemTick()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::ExecuteQueuedEvents();
|
||||
}
|
||||
|
||||
void StaticMeshThumbnailRenderer::RenderThumbnail(AZ::Data::AssetId assetId, int thumbnailSize)
|
||||
{
|
||||
m_previewControl->setFixedSize(thumbnailSize, thumbnailSize);
|
||||
|
||||
// get asset type name
|
||||
AZ::Data::AssetInfo info;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(info, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, assetId);
|
||||
AZ::Data::AssetType assetType = info.m_assetType;
|
||||
QString assetTypeName;
|
||||
AZ::AssetTypeInfoBus::EventResult(assetTypeName, assetType, &AZ::AssetTypeInfo::GetAssetTypeDisplayName);
|
||||
|
||||
QPixmap thumbnail;
|
||||
|
||||
if (Render(thumbnail, assetId, thumbnailSize))
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(assetId,
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailRendered, thumbnail);
|
||||
}
|
||||
else
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(assetId,
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender);
|
||||
}
|
||||
}
|
||||
|
||||
bool StaticMeshThumbnailRenderer::Installed() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StaticMeshThumbnailRenderer::Render(QPixmap& thumbnail, AZ::Data::AssetId assetId, int thumbnailSize) const
|
||||
{
|
||||
// get filepath
|
||||
AZStd::string path;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
path,
|
||||
&AZ::Data::AssetCatalogRequests::GetAssetPathById,
|
||||
assetId);
|
||||
|
||||
m_previewControl->SetMaterial(nullptr);
|
||||
m_previewControl->LoadFile(path.c_str());
|
||||
m_previewControl->FitToScreen();
|
||||
|
||||
gEnv->p3DEngine->Update();
|
||||
gEnv->pSystem->GetStreamEngine()->Update();
|
||||
|
||||
m_previewControl->Update(true);
|
||||
m_previewControl->repaint();
|
||||
CImageEx img;
|
||||
// getimageoffscreen actually requires a real operating system window handle resource, which hiding the window can cause
|
||||
// to be lost.
|
||||
m_previewControl->GetImageOffscreen(img, QSize(thumbnailSize, thumbnailSize));
|
||||
m_previewControl->hide();
|
||||
|
||||
if (img.IsValid())
|
||||
{
|
||||
// this can fail if the request to draw the thumbnail was queued up but then the window
|
||||
// was hidden or deleted in the interim.
|
||||
thumbnail = QPixmap::fromImage(QImage(reinterpret_cast<uchar*>(img.GetData()),
|
||||
img.GetWidth(), img.GetHeight(), QImage::Format_ARGB32)).copy();
|
||||
img.Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* 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 <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
|
||||
class CPreviewModelCtrl;
|
||||
|
||||
//! Loads thumbnails that require acccess to renderer
|
||||
class StaticMeshThumbnailRenderer
|
||||
: public AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::Handler
|
||||
, public AZ::SystemTickBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(StaticMeshThumbnailRenderer, AZ::SystemAllocator, 0)
|
||||
|
||||
StaticMeshThumbnailRenderer();
|
||||
~StaticMeshThumbnailRenderer();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TickBus
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void OnSystemTick() override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ThumbnailerRendererRequests
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void RenderThumbnail(AZ::Data::AssetId assetId, int thumbnailSize) override;
|
||||
bool Installed() const override;
|
||||
|
||||
private:
|
||||
AZ::Data::AssetType m_assetType;
|
||||
AZStd::unique_ptr<CPreviewModelCtrl> m_previewControl;
|
||||
|
||||
bool Render(QPixmap& thumbnail, AZ::Data::AssetId assetId, int thumbnailSize) const;
|
||||
};
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* 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 "TextureThumbnailRenderer.h"
|
||||
|
||||
// AzCore
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/AssetBrowser/EBusFindAssetTypeByName.h>
|
||||
|
||||
// Editor
|
||||
#include "Util/Image.h"
|
||||
#include "Util/ImageUtil.h"
|
||||
|
||||
|
||||
TextureThumbnailRenderer::TextureThumbnailRenderer()
|
||||
{
|
||||
EBusFindAssetTypeByName result("Texture");
|
||||
AZ::AssetTypeInfoBus::BroadcastResult(result, &AZ::AssetTypeInfo::GetAssetType);
|
||||
m_assetType = result.GetAssetType();
|
||||
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::Handler::BusConnect(m_assetType);
|
||||
AZ::SystemTickBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
TextureThumbnailRenderer::~TextureThumbnailRenderer()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::Handler::BusDisconnect();
|
||||
AZ::SystemTickBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void TextureThumbnailRenderer::OnSystemTick()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::ExecuteQueuedEvents();
|
||||
}
|
||||
|
||||
void TextureThumbnailRenderer::RenderThumbnail(AZ::Data::AssetId assetId, int thumbnailSize)
|
||||
{
|
||||
QPixmap thumbnail;
|
||||
|
||||
if (Render(thumbnail, assetId, thumbnailSize))
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(assetId,
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailRendered, thumbnail);
|
||||
}
|
||||
else
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(assetId,
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender);
|
||||
}
|
||||
}
|
||||
|
||||
bool TextureThumbnailRenderer::Installed() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TextureThumbnailRenderer::Render(QPixmap& thumbnail, AZ::Data::AssetId assetId, int thumbnailSize) const
|
||||
{
|
||||
// get filepath
|
||||
AZStd::string path;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
path,
|
||||
&AZ::Data::AssetCatalogRequests::GetAssetPathById,
|
||||
assetId);
|
||||
|
||||
CImageEx img;
|
||||
if (!CImageUtil::LoadImage(path.c_str(), img))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int* data = img.GetData();
|
||||
|
||||
if (!data)
|
||||
{
|
||||
img.Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 == img.GetWidth() || 0 == img.GetHeight())
|
||||
{
|
||||
img.Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
thumbnail = QPixmap::fromImage(QImage(reinterpret_cast<uchar*>(data), img.GetWidth(), img.GetHeight(), QImage::Format_ARGB32)
|
||||
.scaled(thumbnailSize, thumbnailSize, Qt::IgnoreAspectRatio)).copy();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* 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 <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
|
||||
//! Loads thumbnails that require acccess to renderer
|
||||
class TextureThumbnailRenderer
|
||||
: public AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::Handler
|
||||
, public AZ::SystemTickBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(TextureThumbnailRenderer, AZ::SystemAllocator, 0)
|
||||
|
||||
TextureThumbnailRenderer();
|
||||
~TextureThumbnailRenderer();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TickBus
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void OnSystemTick() override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ThumbnailerRendererRequests
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void RenderThumbnail(AZ::Data::AssetId assetId, int thumbnailSize) override;
|
||||
bool Installed() const override;
|
||||
|
||||
private:
|
||||
AZ::Data::AssetType m_assetType;
|
||||
|
||||
bool Render(QPixmap& thumbnail, AZ::Data::AssetId assetId, int thumbnailSize) const;
|
||||
};
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
* 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 <AzCore/Asset/AssetTypeInfoBus.h>
|
||||
#include <IStreamEngine.h>
|
||||
#include <Editor/Thumbnails/ThumbnailRenderer.h>
|
||||
#include <Editor/Controls/PreviewModelCtrl.h>
|
||||
#include <Editor/Material/MaterialManager.h>
|
||||
|
||||
const char* MATERIAL_PREVIEW_MODEL_FILE = "Editor/Objects/MtlSphere.cgf";
|
||||
|
||||
ThumbnailRenderer::ThumbnailRenderer()
|
||||
{
|
||||
m_previewControl = std::make_unique<CPreviewModelCtrl>();
|
||||
m_previewControl->SetGrid(false);
|
||||
m_previewControl->SetAxis(false);
|
||||
m_previewControl->SetClearColor(ColorF(0, 0, 0, 0));
|
||||
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestsBus::Handler::BusConnect();
|
||||
AZ::SystemTickBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
ThumbnailRenderer::~ThumbnailRenderer()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestsBus::Handler::BusDisconnect();
|
||||
AZ::SystemTickBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void ThumbnailRenderer::OnSystemTick()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestsBus::ExecuteQueuedEvents();
|
||||
}
|
||||
|
||||
void ThumbnailRenderer::RenderThumbnail(AZ::Data::AssetId assetId, int thumbnailSize)
|
||||
{
|
||||
m_previewControl->setFixedSize(thumbnailSize, thumbnailSize);
|
||||
|
||||
// get asset type name
|
||||
AZ::Data::AssetInfo info;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(info, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, assetId);
|
||||
AZ::Data::AssetType assetType = info.m_assetType;
|
||||
QString assetTypeName;
|
||||
AZ::AssetTypeInfoBus::EventResult(assetTypeName, assetType, &AZ::AssetTypeInfo::GetAssetTypeDisplayName);
|
||||
|
||||
// get filepath
|
||||
AZStd::string path;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
path,
|
||||
&AZ::Data::AssetCatalogRequests::GetAssetPathById,
|
||||
assetId);
|
||||
|
||||
bool success = false;
|
||||
QPixmap thumbnail;
|
||||
|
||||
if (assetTypeName == "Static Mesh")
|
||||
{
|
||||
success = RenderMesh(thumbnail, path.c_str(), thumbnailSize);
|
||||
}
|
||||
else if (assetTypeName == "Material")
|
||||
{
|
||||
success = RenderMaterial(thumbnail, path.c_str(), thumbnailSize);
|
||||
}
|
||||
else if (assetTypeName == "Texture")
|
||||
{
|
||||
success = RenderTexture(thumbnail, path.c_str(), thumbnailSize);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationsBus::Event(assetId,
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailRendered, thumbnail);
|
||||
}
|
||||
else
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationsBus::Event(assetId,
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender);
|
||||
}
|
||||
}
|
||||
|
||||
bool ThumbnailRenderer::RenderMesh(QPixmap& thumbnail, const char* path, int thumbnailSize) const
|
||||
{
|
||||
m_previewControl->SetMaterial(nullptr);
|
||||
m_previewControl->LoadFile(path);
|
||||
m_previewControl->FitToScreen();
|
||||
|
||||
gEnv->p3DEngine->Update();
|
||||
gEnv->pSystem->GetStreamEngine()->Update();
|
||||
|
||||
m_previewControl->Update(true);
|
||||
m_previewControl->repaint();
|
||||
m_previewControl->hide();
|
||||
|
||||
CImageEx img;
|
||||
m_previewControl->GetImageOffscreen(img, QSize(thumbnailSize, thumbnailSize));
|
||||
|
||||
thumbnail = QPixmap::fromImage(QImage(reinterpret_cast<uchar*>(img.GetData()),
|
||||
img.GetWidth(), img.GetHeight(), QImage::Format_ARGB32)).copy();
|
||||
|
||||
img.Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ThumbnailRenderer::RenderMaterial(QPixmap& thumbnail, const char* path, int thumbnailSize) const
|
||||
{
|
||||
auto material = GetIEditor()->GetMaterialManager()->LoadMaterial(path, false);
|
||||
m_previewControl->LoadFile(MATERIAL_PREVIEW_MODEL_FILE);
|
||||
m_previewControl->SetMaterial(material);
|
||||
m_previewControl->FitToScreen();
|
||||
|
||||
gEnv->p3DEngine->Update();
|
||||
gEnv->pSystem->GetStreamEngine()->Update();
|
||||
|
||||
m_previewControl->Update(true);
|
||||
m_previewControl->repaint();
|
||||
m_previewControl->hide();
|
||||
|
||||
CImageEx img;
|
||||
m_previewControl->GetImageOffscreen(img, QSize(thumbnailSize, thumbnailSize));
|
||||
|
||||
thumbnail = QPixmap::fromImage(QImage(reinterpret_cast<uchar*>(img.GetData()),
|
||||
img.GetWidth(), img.GetHeight(), QImage::Format_ARGB32)).copy();
|
||||
|
||||
img.Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ThumbnailRenderer::RenderTexture(QPixmap& thumbnail, const char* path, int thumbnailSize) const
|
||||
{
|
||||
CImageEx img;
|
||||
if (!CImageUtil::LoadImage(path, img))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int* pData = img.GetData();
|
||||
|
||||
if (!pData)
|
||||
{
|
||||
img.Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 == img.GetWidth() || 0 == img.GetHeight())
|
||||
{
|
||||
img.Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
thumbnail = QPixmap::fromImage(QImage(reinterpret_cast<uchar*>(pData), img.GetWidth(), img.GetHeight(), QImage::Format_ARGB32)
|
||||
.scaled(thumbnailSize, thumbnailSize, Qt::IgnoreAspectRatio)).copy();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* 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 <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
|
||||
class CPreviewModelCtrl;
|
||||
|
||||
//! Loads thumbnails that require acccess to renderer
|
||||
class ThumbnailRenderer
|
||||
: public AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestsBus::Handler
|
||||
, public AZ::SystemTickBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(ThumbnailRenderer, AZ::SystemAllocator, 0)
|
||||
|
||||
ThumbnailRenderer();
|
||||
~ThumbnailRenderer();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TickBus
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void OnSystemTick() override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ThumbnailerRendererRequests
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void RenderThumbnail(AZ::Data::AssetId assetId, int thumbnailSize) override;
|
||||
|
||||
private:
|
||||
AZStd::unique_ptr<CPreviewModelCtrl> m_previewControl;
|
||||
|
||||
bool RenderMesh(QPixmap& thumbnail, const char* path, int thumbnailSize) const;
|
||||
bool RenderMaterial(QPixmap& thumbnail, const char* path, int thumbnailSize) const;
|
||||
bool RenderTexture(QPixmap& thumbnail, const char* path, int thumbnailSize) const;
|
||||
};
|
||||
@@ -27,10 +27,8 @@ public:
|
||||
CSmartVariableArray mv_table;
|
||||
CSmartVariable<float> mv_duration;
|
||||
CSmartVariable<float> mv_timeStep;
|
||||
CSmartVariableEnum<QString> mv_format;
|
||||
CSmartVariable<QString> mv_prefix;
|
||||
CSmartVariable<QString> mv_folder;
|
||||
CSmartVariableEnum<int> mv_captureBufferType;
|
||||
CSmartVariable<bool> mv_once;
|
||||
|
||||
virtual void OnCreateVars()
|
||||
@@ -38,23 +36,11 @@ public:
|
||||
mv_duration.GetVar()->SetLimits(0, 100000.0f);
|
||||
mv_timeStep.GetVar()->SetLimits(0.001f, 1.0f);
|
||||
|
||||
// mv_format enumerations must match ICaptureKey::CaptureFileFormat enum
|
||||
mv_format.SetEnumList(NULL);
|
||||
mv_format->AddEnumItem("jpg", "jpg");
|
||||
mv_format->AddEnumItem("tga", "tga");
|
||||
mv_format->AddEnumItem("tif", "tif");
|
||||
|
||||
mv_captureBufferType.SetEnumList(NULL);
|
||||
mv_captureBufferType->AddEnumItem("Color", ICaptureKey::Color);
|
||||
mv_captureBufferType->AddEnumItem("Color+Alpha", ICaptureKey::ColorWithAlpha);
|
||||
|
||||
AddVariable(mv_table, "Key Properties");
|
||||
AddVariable(mv_table, mv_duration, "Duration");
|
||||
AddVariable(mv_table, mv_timeStep, "Time Step");
|
||||
AddVariable(mv_table, mv_format, "Output Format");
|
||||
AddVariable(mv_table, mv_prefix, "Output Prefix");
|
||||
AddVariable(mv_table, mv_folder, "Output Folder");
|
||||
AddVariable(mv_table, mv_captureBufferType, "Buffer(s) to capture");
|
||||
AddVariable(mv_table, mv_once, "Just one frame?");
|
||||
}
|
||||
bool SupportTrackType(const CAnimParamType& paramType, [[maybe_unused]] EAnimCurveType trackType, [[maybe_unused]] AnimValueType valueType) const
|
||||
@@ -98,10 +84,8 @@ bool CCaptureKeyUIControls::OnKeySelectionChange(CTrackViewKeyBundle& selectedKe
|
||||
|
||||
mv_duration = captureKey.duration;
|
||||
mv_timeStep = captureKey.timeStep;
|
||||
mv_format = captureKey.GetFormat();
|
||||
mv_prefix = captureKey.prefix.c_str();
|
||||
mv_folder = captureKey.folder.c_str();
|
||||
mv_captureBufferType = captureKey.captureBufferIndex;
|
||||
mv_once = captureKey.once;
|
||||
|
||||
bAssigned = true;
|
||||
@@ -132,25 +116,7 @@ void CCaptureKeyUIControls::OnUIChange(IVariable* pVar, CTrackViewKeyBundle& sel
|
||||
|
||||
SyncValue(mv_duration, captureKey.duration, false, pVar);
|
||||
SyncValue(mv_timeStep, captureKey.timeStep, false, pVar);
|
||||
if (pVar == mv_format.GetVar())
|
||||
{
|
||||
if (QString::compare(mv_format, "jpg") == 0)
|
||||
{
|
||||
captureKey.FormatJPG();
|
||||
}
|
||||
else if (QString::compare(mv_format, "bmp") == 0)
|
||||
{
|
||||
captureKey.FormatBMP();
|
||||
}
|
||||
else if (QString::compare(mv_format, "hdr") == 0)
|
||||
{
|
||||
captureKey.FormatHDR();
|
||||
}
|
||||
else
|
||||
{
|
||||
captureKey.FormatTGA();
|
||||
}
|
||||
}
|
||||
|
||||
if (pVar == mv_folder.GetVar())
|
||||
{
|
||||
QString sFolder = mv_folder;
|
||||
@@ -161,14 +127,12 @@ void CCaptureKeyUIControls::OnUIChange(IVariable* pVar, CTrackViewKeyBundle& sel
|
||||
QString sPrefix = mv_prefix;
|
||||
captureKey.prefix = sPrefix.toUtf8().data();
|
||||
}
|
||||
if (pVar == mv_captureBufferType.GetVar())
|
||||
{
|
||||
captureKey.captureBufferIndex = static_cast<ICaptureKey::CaptureBufferType>(static_cast<int>(mv_captureBufferType));
|
||||
}
|
||||
|
||||
SyncValue(mv_once, captureKey.once, false, pVar);
|
||||
|
||||
bool isDuringUndo = false;
|
||||
AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult(isDuringUndo, &AzToolsFramework::ToolsApplicationRequests::Bus::Events::IsDuringUndoRedo);
|
||||
AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult(
|
||||
isDuringUndo, &AzToolsFramework::ToolsApplicationRequests::Bus::Events::IsDuringUndoRedo);
|
||||
|
||||
if (isDuringUndo)
|
||||
{
|
||||
|
||||
@@ -59,18 +59,13 @@ namespace
|
||||
{
|
||||
int fps;
|
||||
const char* fpsDesc;
|
||||
};
|
||||
SFPSPair fps[] = {
|
||||
} fps[] = {
|
||||
{24, "Film(24)"}, {25, "PAL(25)"}, {30, "NTSC(30)"},
|
||||
{48, "Show(48)"}, {50, "PAL Field(50)"}, {60, "NTSC Field(60)"}
|
||||
};
|
||||
|
||||
// The text and ordering of these strings need to match ICaptureKey::CaptureFileFormat. These strings are used
|
||||
// both for the comboBox UI strings as well as the file extension strings
|
||||
const char* imageFormats[ICaptureKey::NumCaptureFileFormats] = { "jpg", "tga", "tif" };
|
||||
|
||||
// The text and ordering of these strings need to match ICaptureKey::CaptureBufferType
|
||||
const char* buffersToCapture[ICaptureKey::NumCaptureBufferTypes] = { "Color", "Color+Alpha" };
|
||||
// currently supported file extensions
|
||||
const char* imageFormatExtensions[] = {"dds", "ppm"};
|
||||
|
||||
const char defaultPresetFilename[] = "defaultBatchRender.preset";
|
||||
|
||||
@@ -170,7 +165,6 @@ void CSequenceBatchRenderDialog::OnInitDialog()
|
||||
connect(m_ui->m_fpsCombo, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &CSequenceBatchRenderDialog::OnFPSChange);
|
||||
connect(m_ui->m_renderList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &CSequenceBatchRenderDialog::OnRenderItemSelChange);
|
||||
connect(m_ui->m_resolutionCombo, activated, this, &CSequenceBatchRenderDialog::OnResolutionSelected);
|
||||
connect(m_ui->m_buffersToCaptureCombo, activated, this, &CSequenceBatchRenderDialog::OnBuffersSelected);
|
||||
connect(m_ui->m_startFrame, editingFinished, this, &CSequenceBatchRenderDialog::OnStartFrameChange);
|
||||
connect(m_ui->m_endFrame, editingFinished, this, &CSequenceBatchRenderDialog::OnEndFrameChange);
|
||||
connect(m_ui->m_imageFormatCombo, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &CSequenceBatchRenderDialog::OnImageFormatChange);
|
||||
@@ -219,25 +213,18 @@ void CSequenceBatchRenderDialog::OnInitDialog()
|
||||
m_ui->m_resolutionCombo->setCurrentIndex(0);
|
||||
|
||||
// Fill the FPS combo box.
|
||||
for (int i = 0; i < arraysize(fps); ++i)
|
||||
for (int i = 0; i < AZStd::size(fps); ++i)
|
||||
{
|
||||
m_ui->m_fpsCombo->addItem(fps[i].fpsDesc);
|
||||
}
|
||||
m_ui->m_fpsCombo->setCurrentIndex(0);
|
||||
|
||||
// Fill the image format combo box.
|
||||
for (int i = 0; i < arraysize(imageFormats); ++i)
|
||||
for (int i = 0; i < AZStd::size(imageFormatExtensions); ++i)
|
||||
{
|
||||
m_ui->m_imageFormatCombo->addItem(imageFormats[i]);
|
||||
m_ui->m_imageFormatCombo->addItem(imageFormatExtensions[i]);
|
||||
}
|
||||
m_ui->m_imageFormatCombo->setCurrentIndex(ICaptureKey::Jpg);
|
||||
|
||||
// Fill the buffers-to-capture combo box.
|
||||
for (int i = 0; i < arraysize(buffersToCapture); ++i)
|
||||
{
|
||||
m_ui->m_buffersToCaptureCombo->addItem(buffersToCapture[i]);
|
||||
}
|
||||
m_ui->m_buffersToCaptureCombo->setCurrentIndex(0);
|
||||
m_ui->m_imageFormatCombo->setCurrentIndex(0);
|
||||
|
||||
m_ui->BATCH_RENDER_FILE_PREFIX->setText("Frame");
|
||||
m_ui->BATCH_RENDER_FILE_PREFIX->setValidator(m_prefixValidator.data());
|
||||
@@ -333,13 +320,8 @@ void CSequenceBatchRenderDialog::OnRenderItemSelChange()
|
||||
m_customFPS = item.fps;
|
||||
m_ui->m_fpsCombo->setCurrentText(QString::number(item.fps));
|
||||
}
|
||||
// capture buffer type
|
||||
m_ui->m_buffersToCaptureCombo->setCurrentIndex(item.bufferIndex);
|
||||
// prefix
|
||||
m_ui->BATCH_RENDER_FILE_PREFIX->setText(item.prefix);
|
||||
// format
|
||||
m_ui->m_imageFormatCombo->setCurrentIndex(item.formatIndex);
|
||||
OnBuffersSelected();
|
||||
|
||||
m_ui->m_disableDebugInfoCheckBox->setChecked(item.disableDebugInfo);
|
||||
|
||||
@@ -702,8 +684,7 @@ void CSequenceBatchRenderDialog::SaveOutputOptions(const QString& pathname) cons
|
||||
|
||||
// Capture options (format, buffer, prefix, create_video)
|
||||
XmlNodeRef imageNode = batchRenderOptionsNode->newChild("image");
|
||||
imageNode->setAttr("format", m_ui->m_imageFormatCombo->currentIndex() % arraysize(imageFormats));
|
||||
imageNode->setAttr("bufferstocapture", m_ui->m_buffersToCaptureCombo->currentIndex());
|
||||
imageNode->setAttr("format", m_ui->m_imageFormatCombo->currentIndex() % arraysize(imageFormatExtensions));
|
||||
const QString prefix = m_ui->BATCH_RENDER_FILE_PREFIX->text();
|
||||
imageNode->setAttr("prefix", prefix.toUtf8().data());
|
||||
bool disableDebugInfo = m_ui->m_disableDebugInfoCheckBox->isChecked();
|
||||
@@ -803,9 +784,6 @@ bool CSequenceBatchRenderDialog::LoadOutputOptions(const QString& pathname)
|
||||
imageNode->getAttr("format", curSel);
|
||||
m_ui->m_imageFormatCombo->setCurrentIndex(curSel);
|
||||
curSel = CB_ERR;
|
||||
imageNode->getAttr("bufferstocapture", curSel);
|
||||
m_ui->m_buffersToCaptureCombo->setCurrentIndex(curSel);
|
||||
OnBuffersSelected();
|
||||
m_ui->BATCH_RENDER_FILE_PREFIX->setText(imageNode->getAttr("prefix"));
|
||||
bool disableDebugInfo = false;
|
||||
imageNode->getAttr("disabledebuginfo", disableDebugInfo);
|
||||
@@ -919,25 +897,7 @@ void CSequenceBatchRenderDialog::CaptureItemStart()
|
||||
}
|
||||
|
||||
// Set specific capture options for this item.
|
||||
m_renderContext.captureOptions.captureBufferIndex = renderItem.bufferIndex;
|
||||
m_renderContext.captureOptions.prefix = renderItem.prefix.toUtf8().data();
|
||||
switch (renderItem.formatIndex)
|
||||
{
|
||||
case ICaptureKey::Jpg:
|
||||
m_renderContext.captureOptions.FormatJPG();
|
||||
break;
|
||||
case ICaptureKey::Tga:
|
||||
m_renderContext.captureOptions.FormatTGA();
|
||||
break;
|
||||
case ICaptureKey::Tif:
|
||||
m_renderContext.captureOptions.FormatTIF();
|
||||
break;
|
||||
default:
|
||||
// fall back to tga, the most general of the formats
|
||||
gEnv->pLog->LogWarning("Unhandled file format type detected in CSequenceBatchRenderDialog::CaptureItemStart(), using tga");
|
||||
m_renderContext.captureOptions.FormatTGA();
|
||||
break;
|
||||
}
|
||||
|
||||
Range rng = nextSequence->GetTimeRange();
|
||||
m_renderContext.captureOptions.duration = rng.end - rng.start;
|
||||
@@ -967,6 +927,9 @@ void CSequenceBatchRenderDialog::CaptureItemStart()
|
||||
++i;
|
||||
}
|
||||
|
||||
// create a new folder before writing any files
|
||||
QDir().mkdir(finalFolder);
|
||||
|
||||
m_renderContext.captureOptions.folder = finalFolder.toUtf8().data();
|
||||
|
||||
// Change the resolution.
|
||||
@@ -1131,17 +1094,18 @@ void CSequenceBatchRenderDialog::OnUpdateEnd(IAnimSequence* sequence)
|
||||
sequence->SetFlags(m_renderContext.flagBU);
|
||||
sequence->SetTimeRange(m_renderContext.rangeBU);
|
||||
sequence->SetActiveDirector(m_renderContext.pActiveDirectorBU);
|
||||
|
||||
const auto imageFormat = m_ui->m_imageFormatCombo->currentText();
|
||||
|
||||
SRenderItem renderItem = m_renderItems[m_renderContext.currentItemIndex];
|
||||
if (m_bFFMPEGCommandAvailable
|
||||
&& renderItem.bCreateVideo)
|
||||
if (m_bFFMPEGCommandAvailable && renderItem.bCreateVideo)
|
||||
{
|
||||
// Create a video using the ffmpeg plug-in from captured images.
|
||||
m_renderContext.processingFFMPEG = true;
|
||||
|
||||
AZStd::string outputFolder = m_renderContext.captureOptions.folder;
|
||||
auto future = QtConcurrent::run(
|
||||
[renderItem, outputFolder]
|
||||
[renderItem, outputFolder, imageFormat]
|
||||
{
|
||||
AZStd::string outputFile;
|
||||
AzFramework::StringFunc::Path::Join(outputFolder.c_str(), renderItem.prefix.toUtf8().data(), outputFile);
|
||||
@@ -1158,15 +1122,14 @@ void CSequenceBatchRenderDialog::OnUpdateEnd(IAnimSequence* sequence)
|
||||
|
||||
// Create the input file string, leave the %06d unexpanded for the mpeg tool.
|
||||
inputFile += "%06d.";
|
||||
inputFile += imageFormats[renderItem.formatIndex];
|
||||
inputFile += imageFormat;
|
||||
|
||||
// Replace the input file
|
||||
command = command.replace(inputFileDefine, inputFile);
|
||||
|
||||
// Run the command
|
||||
GetIEditor()->ExecuteCommand(command);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// Use a watcher to set a flag when the mpeg processing is complete.
|
||||
connect(&m_renderContext.processingFFMPEGWatcher, &QFutureWatcher<void>::finished, this, [this]()
|
||||
@@ -1339,8 +1302,9 @@ void CSequenceBatchRenderDialog::OnKickIdle()
|
||||
|
||||
if (canBeginFrameCapture())
|
||||
{
|
||||
const AZStd::string fileName = AZStd::string::format("Frame_%06d", m_renderContext.frameNumber);
|
||||
|
||||
AZStd::string filePath;
|
||||
AZStd::string fileName = AZStd::string::format("Frame_%06d.dds", m_renderContext.frameNumber);
|
||||
AzFramework::StringFunc::Path::Join(
|
||||
m_renderContext.captureOptions.folder.c_str(), fileName.c_str(), filePath, /*caseInsensitive=*/true,
|
||||
/*normalize=*/false);
|
||||
@@ -1352,13 +1316,34 @@ void CSequenceBatchRenderDialog::OnKickIdle()
|
||||
GetIEditor()->GetMovieSystem()->ControlCapture();
|
||||
};
|
||||
|
||||
const auto imageFormatExtension = m_ui->m_imageFormatCombo->currentText();
|
||||
// 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())
|
||||
// currently only .dds and .ppm
|
||||
const auto readbackCallback = [filePath,
|
||||
imageFormatExtension](const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult) {
|
||||
const auto imageFormatExtensionUtf8 = imageFormatExtension.toUtf8();
|
||||
const auto imageFormatExtensionCstr = imageFormatExtensionUtf8.constData();
|
||||
|
||||
const AZStd::string fileName = AZStd::string::format("%s.%s", filePath.c_str(), imageFormatExtensionCstr);
|
||||
if (AZ::StringFunc::Equal(imageFormatExtensionCstr, "dds"))
|
||||
{
|
||||
AZ_Printf("TrackView", "Frame capture failed: %s", result.m_errorMessage.value().c_str());
|
||||
if (const AZ::Render::FrameCaptureOutputResult result = AZ::Render::DdsFrameCaptureOutput(fileName, readbackResult);
|
||||
result.m_errorMessage.has_value())
|
||||
{
|
||||
AZ_Printf("TrackView", "Dds frame capture failed: %s", result.m_errorMessage.value().c_str());
|
||||
}
|
||||
}
|
||||
else if (AZ::StringFunc::Equal(imageFormatExtensionCstr, "ppm"))
|
||||
{
|
||||
if (const AZ::Render::FrameCaptureOutputResult result = AZ::Render::PpmFrameCaptureOutput(fileName, readbackResult);
|
||||
result.m_errorMessage.has_value())
|
||||
{
|
||||
AZ_Printf("TrackView", "Ppm frame capture failed: %s", result.m_errorMessage.value().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Printf("TrackView", "Image format .%s not supported", imageFormatExtensionCstr);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1454,15 +1439,6 @@ void CSequenceBatchRenderDialog::OnLoadBatch()
|
||||
// fps
|
||||
itemNode->getAttr("fps", item.fps);
|
||||
|
||||
// format
|
||||
int intAttr;
|
||||
itemNode->getAttr("format", intAttr);
|
||||
item.formatIndex = (intAttr <= ICaptureKey::NumCaptureFileFormats) ? static_cast<ICaptureKey::CaptureFileFormat>(intAttr) : ICaptureKey::Jpg;
|
||||
|
||||
// capture buffer type
|
||||
itemNode->getAttr("bufferstocapture", intAttr);
|
||||
item.bufferIndex = (intAttr <= ICaptureKey::NumCaptureBufferTypes) ? static_cast<ICaptureKey::CaptureBufferType>(intAttr) : ICaptureKey::Color;
|
||||
|
||||
// prefix
|
||||
item.prefix = itemNode->getAttr("prefix");
|
||||
|
||||
@@ -1515,12 +1491,6 @@ void CSequenceBatchRenderDialog::OnSaveBatch()
|
||||
// fps
|
||||
itemNode->setAttr("fps", item.fps);
|
||||
|
||||
// format
|
||||
itemNode->setAttr("format", item.formatIndex);
|
||||
|
||||
// capture buffer type
|
||||
itemNode->setAttr("bufferstocapture", item.bufferIndex);
|
||||
|
||||
// prefix
|
||||
itemNode->setAttr("prefix", item.prefix.toUtf8().data());
|
||||
|
||||
@@ -1581,12 +1551,8 @@ bool CSequenceBatchRenderDialog::SetUpNewRenderItem(SRenderItem& item)
|
||||
{
|
||||
item.fps = fps[m_ui->m_fpsCombo->currentIndex()].fps;
|
||||
}
|
||||
// capture buffer type
|
||||
item.bufferIndex = static_cast<ICaptureKey::CaptureBufferType>(m_ui->m_buffersToCaptureCombo->currentIndex());
|
||||
// prefix
|
||||
item.prefix = m_ui->BATCH_RENDER_FILE_PREFIX->text();
|
||||
// format
|
||||
item.formatIndex = static_cast<ICaptureKey::CaptureFileFormat>(m_ui->m_imageFormatCombo->currentIndex() % arraysize(imageFormats));
|
||||
// disable debug info
|
||||
item.disableDebugInfo = m_ui->m_disableDebugInfoCheckBox->isChecked();
|
||||
// create_video
|
||||
@@ -1632,36 +1598,13 @@ void CSequenceBatchRenderDialog::AddItem(const SRenderItem& item)
|
||||
|
||||
QString CSequenceBatchRenderDialog::GetCaptureItemString(const SRenderItem& item) const
|
||||
{
|
||||
return QString::fromLatin1("%1_%2_%3-%4(%5x%6,%7,%8)%9").arg(item.pSequence->GetName())
|
||||
return QString::fromLatin1("%1_%2_%3-%4(%5x%6,%7)%8").arg(item.pSequence->GetName())
|
||||
.arg(item.pDirectorNode->GetName())
|
||||
.arg(int(item.frameRange.start * m_fpsForTimeToFrameConversion))
|
||||
.arg(int(item.frameRange.end * m_fpsForTimeToFrameConversion))
|
||||
.arg(getResWidth(item.resW)).arg(getResHeight(item.resH)).arg(item.fps).arg(buffersToCapture[item.bufferIndex])
|
||||
.arg(getResWidth(item.resW)).arg(getResHeight(item.resH)).arg(item.fps)
|
||||
.arg(item.bCreateVideo ? "[v]" : "");
|
||||
}
|
||||
void CSequenceBatchRenderDialog::OnBuffersSelected()
|
||||
{
|
||||
int curSel = m_ui->m_buffersToCaptureCombo->currentIndex();
|
||||
const ICaptureKey::CaptureBufferType bufferType = (curSel >= ICaptureKey::NumCaptureBufferTypes ? ICaptureKey::Color : static_cast<ICaptureKey::CaptureBufferType>(curSel));
|
||||
|
||||
switch (bufferType)
|
||||
{
|
||||
case ICaptureKey::Color:
|
||||
// allow any format for color buffer
|
||||
m_ui->m_imageFormatCombo->setEnabled(true);
|
||||
break;
|
||||
case ICaptureKey::ColorWithAlpha:
|
||||
// only tga supports alpha for now - set it and disable the ability to change it
|
||||
m_ui->m_imageFormatCombo->setCurrentIndex(ICaptureKey::Tga);
|
||||
m_ui->m_imageFormatCombo->setEnabled(false);
|
||||
break;
|
||||
default:
|
||||
gEnv->pLog->LogWarning("Unhandle capture buffer type used in CSequenceBatchRenderDialog::OnBuffersSelected()");
|
||||
break;
|
||||
}
|
||||
|
||||
CheckForEnableUpdateButton();
|
||||
}
|
||||
|
||||
void CSequenceBatchRenderDialog::UpdateSpinnerProgressMessage(const char* description)
|
||||
{
|
||||
|
||||
@@ -62,7 +62,6 @@ protected:
|
||||
void OnEndFrameChange();
|
||||
void OnLoadBatch();
|
||||
void OnSaveBatch();
|
||||
void OnBuffersSelected();
|
||||
void OnKickIdle();
|
||||
void OnCancelRender();
|
||||
|
||||
@@ -80,8 +79,6 @@ protected:
|
||||
Range frameRange;
|
||||
int resW, resH;
|
||||
int fps;
|
||||
ICaptureKey::CaptureFileFormat formatIndex;
|
||||
ICaptureKey::CaptureBufferType bufferIndex;
|
||||
QString folder;
|
||||
QString prefix;
|
||||
QStringList cvars;
|
||||
@@ -99,8 +96,6 @@ protected:
|
||||
&& frameRange == item.frameRange
|
||||
&& resW == item.resW && resH == item.resH
|
||||
&& fps == item.fps
|
||||
&& formatIndex == item.formatIndex
|
||||
&& bufferIndex == item.bufferIndex
|
||||
&& folder == item.folder
|
||||
&& prefix == item.prefix
|
||||
&& cvars == item.cvars
|
||||
|
||||
@@ -162,24 +162,14 @@
|
||||
<string>Capture Options</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="m_createVideoCheckBox">
|
||||
<property name="text">
|
||||
<string>Buffer(s) to capture:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
<string>Create a video (mp4)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" colspan="2">
|
||||
<widget class="QLineEdit" name="BATCH_RENDER_FILE_PREFIX">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>File prefix:</string>
|
||||
@@ -189,23 +179,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QComboBox" name="m_imageFormatCombo"/>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="3">
|
||||
<widget class="QComboBox" name="m_buffersToCaptureCombo"/>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="4">
|
||||
<widget class="QCheckBox" name="m_disableDebugInfoCheckBox">
|
||||
<property name="text">
|
||||
<string>Disable Debug Info</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="4">
|
||||
<widget class="QCheckBox" name="m_createVideoCheckBox">
|
||||
<property name="text">
|
||||
<string>Create a video (mp4)</string>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="BATCH_RENDER_FILE_PREFIX">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -219,6 +196,20 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="m_disableDebugInfoCheckBox">
|
||||
<property name="text">
|
||||
<string>Disable Debug Info</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="m_imageFormatCombo">
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContentsOnFirstShow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -244,8 +235,8 @@
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:4.125pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8.25pt;"><br /></p></body></html></string>
|
||||
</property>
|
||||
<property name="acceptRichText">
|
||||
<bool>false</bool>
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
#include "EditorUtils.h"
|
||||
|
||||
#include "EditorToolsApplicationAPI.h"
|
||||
|
||||
// Qt
|
||||
#include <QColor>
|
||||
#include <QMessageBox>
|
||||
@@ -278,5 +280,26 @@ namespace EditorUtils
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* LevelFile::GetOldCryFileExtension()
|
||||
{
|
||||
const char* oldCryExtension = nullptr;
|
||||
EditorInternal::EditorToolsApplicationRequestBus::BroadcastResult(
|
||||
oldCryExtension, &EditorInternal::EditorToolsApplicationRequests::GetOldCryLevelExtension);
|
||||
|
||||
AZ_Assert(oldCryExtension, "Cannot retrieve file extension");
|
||||
return oldCryExtension;
|
||||
}
|
||||
|
||||
const char* LevelFile::GetDefaultFileExtension()
|
||||
{
|
||||
const char* levelExtension = nullptr;
|
||||
EditorInternal::EditorToolsApplicationRequestBus::BroadcastResult(
|
||||
levelExtension, &EditorInternal::EditorToolsApplicationRequests::GetLevelExtension);
|
||||
|
||||
AZ_Assert(levelExtension, "Cannot retrieve file extension");
|
||||
return levelExtension;
|
||||
}
|
||||
|
||||
} // namespace EditorUtils
|
||||
|
||||
|
||||
@@ -176,6 +176,13 @@ namespace EditorUtils
|
||||
AZStd::string m_window;
|
||||
};
|
||||
|
||||
namespace LevelFile
|
||||
{
|
||||
//! Retrieve old cry level file extension (With prepending '.')
|
||||
const char* GetOldCryFileExtension();
|
||||
//! Retrieve default level file extension (With prepending '.')
|
||||
const char* GetDefaultFileExtension();
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -147,6 +147,8 @@ WelcomeScreenDialog::WelcomeScreenDialog(QWidget* pParent)
|
||||
setMinimumSize(minimumSize().width(), newGeometry.height());
|
||||
resize(newGeometry.size());
|
||||
}
|
||||
|
||||
m_levelExtension = EditorUtils::LevelFile::GetDefaultFileExtension();
|
||||
}
|
||||
|
||||
|
||||
@@ -209,34 +211,29 @@ void WelcomeScreenDialog::SetRecentFileList(RecentFileList* pList)
|
||||
int recentListSize = pList->GetSize();
|
||||
for (int i = 0; i < recentListSize; ++i)
|
||||
{
|
||||
if (CFileUtil::Exists(pList->m_arrNames[i], false))
|
||||
const QString& recentFile = pList->m_arrNames[i];
|
||||
if (recentFile.endsWith(m_levelExtension))
|
||||
{
|
||||
QString sCurEntryDir = pList->m_arrNames[i].left(nCurDir);
|
||||
|
||||
if (sCurEntryDir.compare(sCurDir, Qt::CaseInsensitive) != 0)
|
||||
if (CFileUtil::Exists(recentFile, false))
|
||||
{
|
||||
//unavailable entry (wrong directory)
|
||||
continue;
|
||||
QString sCurEntryDir = recentFile.left(nCurDir);
|
||||
if (sCurEntryDir.compare(sCurDir, Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
QString fullPath = recentFile;
|
||||
QString name = Path::GetFileName(fullPath);
|
||||
|
||||
Path::ConvertSlashToBackSlash(fullPath);
|
||||
fullPath = Path::ToUnixPath(fullPath.toLower());
|
||||
fullPath = Path::AddSlash(fullPath);
|
||||
|
||||
if (fullPath.contains(gamePath))
|
||||
{
|
||||
m_pRecentListModel->setStringList(m_pRecentListModel->stringList() << QString(name));
|
||||
m_levels.push_back(std::make_pair(name, recentFile));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//invalid entry (not existing)
|
||||
continue;
|
||||
}
|
||||
|
||||
QString fullPath = pList->m_arrNames[i];
|
||||
QString name = Path::GetFileName(fullPath);
|
||||
|
||||
Path::ConvertSlashToBackSlash(fullPath);
|
||||
fullPath = Path::ToUnixPath(fullPath.toLower());
|
||||
fullPath = Path::AddSlash(fullPath);
|
||||
|
||||
if (fullPath.contains(gamePath))
|
||||
{
|
||||
m_pRecentListModel->setStringList(m_pRecentListModel->stringList() << QString(name));
|
||||
m_levels.push_back(std::make_pair(name, pList->m_arrNames[i]));
|
||||
}
|
||||
}
|
||||
|
||||
ui->recentLevelList->setCurrentIndex(QModelIndex());
|
||||
|
||||
@@ -57,6 +57,7 @@ private:
|
||||
RecentFileList* m_pRecentList;
|
||||
News::ResourceManifest* m_manifest = nullptr;
|
||||
News::ArticleViewContainer* m_articleViewContainer = nullptr;
|
||||
const char* m_levelExtension = nullptr;
|
||||
bool m_waitingOnAsync = true;
|
||||
bool m_messageScrollReported = false;
|
||||
|
||||
|
||||
@@ -341,15 +341,6 @@ set(FILES
|
||||
AzAssetBrowser/Preview/LegacyPreviewer.ui
|
||||
AzAssetBrowser/Preview/LegacyPreviewerFactory.cpp
|
||||
AzAssetBrowser/Preview/LegacyPreviewerFactory.h
|
||||
Thumbnails/MaterialThumbnailRenderer.cpp
|
||||
Thumbnails/MaterialThumbnailRenderer.h
|
||||
Thumbnails/StaticMeshThumbnailRenderer.cpp
|
||||
Thumbnails/StaticMeshThumbnailRenderer.h
|
||||
Thumbnails/TextureThumbnailRenderer.cpp
|
||||
Thumbnails/TextureThumbnailRenderer.h
|
||||
Thumbnails/Example/ThumbnailsSampleWidget.cpp
|
||||
Thumbnails/Example/ThumbnailsSampleWidget.h
|
||||
Thumbnails/Example/ThumbnailsSampleWidget.ui
|
||||
AssetDatabase/AssetDatabaseLocationListener.h
|
||||
AssetDatabase/AssetDatabaseLocationListener.cpp
|
||||
AssetImporter/AssetImporterManager/AssetImporterDragAndDropHandler.cpp
|
||||
|
||||
@@ -152,7 +152,10 @@ ComponentEntityEditorPlugin::ComponentEntityEditorPlugin([[maybe_unused]] IEdito
|
||||
LyViewPane::CategoryTools,
|
||||
levelInspectorOptions);
|
||||
|
||||
if (GetIEditor()->IsPrefabSystemEnabled())
|
||||
bool prefabSystemEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(prefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
if (prefabSystemEnabled)
|
||||
{
|
||||
// Add the new Outliner to the Tools Menu
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <AzToolsFramework/ToolsComponents/GenericComponentWrapper.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorSelectionAccentSystemComponent.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorEntityIconComponentBus.h>
|
||||
#include <AzToolsFramework/Undo/UndoCacheInterface.h>
|
||||
#include <LmbrCentral/Rendering/RenderNodeBus.h>
|
||||
#include <LmbrCentral/Rendering/MeshComponentBus.h>
|
||||
#include <LmbrCentral/Rendering/MaterialOwnerBus.h>
|
||||
@@ -96,12 +97,10 @@ void CComponentEntityObject::UpdatePreemptiveUndoCache()
|
||||
{
|
||||
using namespace AzToolsFramework;
|
||||
|
||||
PreemptiveUndoCache* preemptiveUndoCache = nullptr;
|
||||
ToolsApplicationRequests::Bus::BroadcastResult(preemptiveUndoCache, &ToolsApplicationRequests::GetUndoCache);
|
||||
|
||||
if (preemptiveUndoCache)
|
||||
auto undoCacheInterface = AZ::Interface<UndoSystem::UndoCacheInterface>::Get();
|
||||
if (undoCacheInterface)
|
||||
{
|
||||
preemptiveUndoCache->UpdateCache(m_entityId);
|
||||
undoCacheInterface->UpdateCache(m_entityId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <AzToolsFramework/Undo/UndoSystem.h>
|
||||
#include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiInterface.h>
|
||||
#include <AzToolsFramework/UI/Layer/AddToLayerMenu.h>
|
||||
#include <AzToolsFramework/UI/Prefab/PrefabIntegrationInterface.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/InstanceDataHierarchy.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx>
|
||||
@@ -199,6 +200,12 @@ void SandboxIntegrationManager::Setup()
|
||||
AZ_Assert((m_editorEntityUiInterface != nullptr),
|
||||
"SandboxIntegrationManager requires a EditorEntityUiInterface instance to be present on Setup().");
|
||||
|
||||
m_prefabIntegrationInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabIntegrationInterface>::Get();
|
||||
|
||||
AZ_Assert(
|
||||
(m_prefabIntegrationInterface != nullptr),
|
||||
"SandboxIntegrationManager requires a PrefabIntegrationInterface instance to be present on Setup().");
|
||||
|
||||
AzToolsFramework::Layers::EditorLayerComponentNotificationBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
@@ -259,10 +266,11 @@ void SandboxIntegrationManager::SaveSlice(const bool& QuickPushToFirstLevel)
|
||||
// This event handler is queued on main thread.
|
||||
void SandboxIntegrationManager::OnCatalogAssetAdded(const AZ::Data::AssetId& assetId)
|
||||
{
|
||||
bool isLegacySliceSystemEnabled = true;
|
||||
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(
|
||||
isLegacySliceSystemEnabled, &AzToolsFramework::ToolsApplicationRequests::IsLegacySliceSystemEnabled);
|
||||
if (isLegacySliceSystemEnabled)
|
||||
bool prefabSystemEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
prefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
if (!prefabSystemEnabled)
|
||||
{
|
||||
AZ::SliceComponent* editorRootSlice = nullptr;
|
||||
AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::BroadcastResult(
|
||||
@@ -652,18 +660,21 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con
|
||||
});
|
||||
}
|
||||
|
||||
menu->addSeparator();
|
||||
bool prefabSystemEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(prefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
action = menu->addAction(QObject::tr("Create layer"));
|
||||
QObject::connect(action, &QAction::triggered, [this] { ContextMenu_NewLayer(); });
|
||||
|
||||
SetupLayerContextMenu(menu);
|
||||
AzToolsFramework::EntityIdSet flattenedSelection;
|
||||
GetSelectedEntitiesSetWithFlattenedHierarchy(flattenedSelection);
|
||||
AzToolsFramework::SetupAddToLayerMenu(menu, flattenedSelection, [this] { return ContextMenu_NewLayer(); });
|
||||
|
||||
if (!GetIEditor()->IsPrefabSystemEnabled())
|
||||
if (!prefabSystemEnabled)
|
||||
{
|
||||
menu->addSeparator();
|
||||
|
||||
action = menu->addAction(QObject::tr("Create layer"));
|
||||
QObject::connect(action, &QAction::triggered, [this] { ContextMenu_NewLayer(); });
|
||||
|
||||
SetupLayerContextMenu(menu);
|
||||
AzToolsFramework::EntityIdSet flattenedSelection;
|
||||
GetSelectedEntitiesSetWithFlattenedHierarchy(flattenedSelection);
|
||||
AzToolsFramework::SetupAddToLayerMenu(menu, flattenedSelection, [this] { return ContextMenu_NewLayer(); });
|
||||
|
||||
SetupSliceContextMenu(menu);
|
||||
}
|
||||
else
|
||||
@@ -674,11 +685,18 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con
|
||||
AzToolsFramework::EditorContextMenuBus::Broadcast(&AzToolsFramework::EditorContextMenuEvents::PopulateEditorGlobalContextMenu, menu);
|
||||
}
|
||||
|
||||
action = menu->addAction(QObject::tr("Duplicate"));
|
||||
QObject::connect(action, &QAction::triggered, action, [this] { ContextMenu_Duplicate(); });
|
||||
if (selected.size() == 0)
|
||||
bool prefabWipFeaturesEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
prefabWipFeaturesEnabled, &AzFramework::ApplicationRequests::ArePrefabWipFeaturesEnabled);
|
||||
|
||||
if (!prefabSystemEnabled || (prefabSystemEnabled && prefabWipFeaturesEnabled))
|
||||
{
|
||||
action->setDisabled(true);
|
||||
action = menu->addAction(QObject::tr("Duplicate"));
|
||||
QObject::connect(action, &QAction::triggered, action, [this] { ContextMenu_Duplicate(); });
|
||||
if (selected.size() == 0)
|
||||
{
|
||||
action->setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
action = menu->addAction(QObject::tr("Delete"));
|
||||
@@ -1268,41 +1286,47 @@ AZ::EntityId SandboxIntegrationManager::CreateNewEntityAtPosition(const AZ::Vect
|
||||
{
|
||||
using namespace AzToolsFramework;
|
||||
|
||||
ScopedUndoBatch undo("New Entity");
|
||||
bool prefabSystemEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(prefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
AZ::EntityId newEntityId;
|
||||
|
||||
const AZStd::string name = AZStd::string::format("Entity%d", GetIEditor()->GetObjectManager()->GetObjectCount() + 1);
|
||||
|
||||
EditorEntityContextRequestBus::BroadcastResult(newEntityId, &EditorEntityContextRequests::CreateNewEditorEntity, name.c_str());
|
||||
|
||||
if (newEntityId.IsValid())
|
||||
if (!prefabSystemEnabled)
|
||||
{
|
||||
m_unsavedEntities.insert(newEntityId);
|
||||
const AZStd::string name = AZStd::string::format("Entity%d", GetIEditor()->GetObjectManager()->GetObjectCount() + 1);
|
||||
EditorEntityContextRequestBus::BroadcastResult(newEntityId, &EditorEntityContextRequests::CreateNewEditorEntity, name.c_str());
|
||||
|
||||
AZ::Transform transform = AZ::Transform::CreateIdentity();
|
||||
transform.SetTranslation(pos);
|
||||
if (parentId.IsValid())
|
||||
if (newEntityId.IsValid())
|
||||
{
|
||||
AZ::TransformBus::Event(newEntityId, &AZ::TransformInterface::SetParent, parentId);
|
||||
AZ::TransformBus::Event(newEntityId, &AZ::TransformInterface::SetLocalTM, transform);
|
||||
m_unsavedEntities.insert(newEntityId);
|
||||
|
||||
AZ::Transform transform = AZ::Transform::CreateIdentity();
|
||||
transform.SetTranslation(pos);
|
||||
if (parentId.IsValid())
|
||||
{
|
||||
AZ::TransformBus::Event(newEntityId, &AZ::TransformInterface::SetParent, parentId);
|
||||
AZ::TransformBus::Event(newEntityId, &AZ::TransformInterface::SetLocalTM, transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ::TransformBus::Event(newEntityId, &AZ::TransformInterface::SetWorldTM, transform);
|
||||
}
|
||||
|
||||
// Select the new entity (and deselect others).
|
||||
AzToolsFramework::EntityIdList selection = {newEntityId};
|
||||
|
||||
ScopedUndoBatch undo("New Entity");
|
||||
auto selectionCommand = AZStd::make_unique<AzToolsFramework::SelectionCommand>(selection, "");
|
||||
selectionCommand->SetParent(undo.GetUndoBatch());
|
||||
selectionCommand.release();
|
||||
|
||||
EBUS_EVENT(AzToolsFramework::ToolsApplicationRequests::Bus, SetSelectedEntities, selection);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ::TransformBus::Event(newEntityId, &AZ::TransformInterface::SetWorldTM, transform);
|
||||
}
|
||||
|
||||
// Select the new entity (and deselect others).
|
||||
AzToolsFramework::EntityIdList selection = { newEntityId };
|
||||
|
||||
auto selectionCommand =
|
||||
AZStd::make_unique<AzToolsFramework::SelectionCommand>(selection, "");
|
||||
selectionCommand->SetParent(undo.GetUndoBatch());
|
||||
selectionCommand.release();
|
||||
|
||||
EBUS_EVENT(AzToolsFramework::ToolsApplicationRequests::Bus, SetSelectedEntities, selection);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
newEntityId = m_prefabIntegrationInterface->CreateNewEntityAtPosition(pos, parentId);
|
||||
}
|
||||
return newEntityId;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,11 @@ namespace AzToolsFramework
|
||||
{
|
||||
class AssetSelectionModel;
|
||||
}
|
||||
|
||||
namespace Prefab
|
||||
{
|
||||
class PrefabIntegrationInterface;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -383,6 +388,7 @@ private:
|
||||
AzToolsFramework::Prefab::PrefabIntegrationManager m_prefabIntegrationManager;
|
||||
|
||||
AzToolsFramework::EditorEntityUiInterface* m_editorEntityUiInterface = nullptr;
|
||||
AzToolsFramework::Prefab::PrefabIntegrationInterface* m_prefabIntegrationInterface = nullptr;
|
||||
|
||||
// Overrides UI styling and behavior for Layer Entities
|
||||
AzToolsFramework::LayerUiHandler m_layerUiOverrideHandler;
|
||||
|
||||
@@ -55,8 +55,6 @@ namespace ProjectSettingsTool
|
||||
->Attribute(Attributes::FuncValidator, ConvertFunctorToVoid(&Validators::FileNameOrEmpty))
|
||||
->Attribute(Attributes::PropertyIdentfier, Identfiers::ProductName)
|
||||
->Attribute(Attributes::LinkedProperty, Identfiers::ExecutableName)
|
||||
->DataElement(Handlers::QValidatedLineEdit, &BaseSettings::m_sysDllGame, "Game Dll Name", "The name of the project's dll.")
|
||||
->Attribute(Attributes::FuncValidator, ConvertFunctorToVoid(&Validators::FileNameOrEmpty))
|
||||
->DataElement(Handlers::QValidatedLineEdit, &BaseSettings::m_projectOutputFolder, "Output Folder", "The folder the packed project will be exported to.")
|
||||
->DataElement(Handlers::QValidatedLineEdit, &BaseSettings::m_codeFolder, "Code Folder (legacy)", "A legacy setting specifing the folder for this project's code.")
|
||||
;
|
||||
|
||||
Reference in New Issue
Block a user