Merge branch 'main' into hasareej_LYN-2475_viewportui_switcher
This commit is contained in:
+1
-1
@@ -36,4 +36,4 @@ namespace AzToolsFramework
|
||||
};
|
||||
|
||||
using EditorAnimationSystemRequestsBus = AZ::EBus<EditorAnimationSystemRequests>;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -52,4 +52,4 @@ namespace AzToolsFramework
|
||||
|
||||
using EntityCompositionNotificationBus = AZ::EBus<EntityCompositionNotifications>;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,16 +578,6 @@ namespace AzToolsFramework
|
||||
*/
|
||||
virtual bool IsEditorInIsolationMode() = 0;
|
||||
|
||||
/*!
|
||||
* Get the engine root path that the current tool is running under.
|
||||
*/
|
||||
virtual const char* GetEngineRootPath() const = 0;
|
||||
|
||||
/**
|
||||
* Get the version of the engine the current tools application is running under
|
||||
*/
|
||||
virtual const char* GetEngineVersion() const = 0;
|
||||
|
||||
/**
|
||||
* Creates and adds a new entity to the tools application from components which match at least one of the requiredTags
|
||||
* The tag matching occurs on AZ::Edit::SystemComponentTags attribute from the reflected class data in the serialization context
|
||||
@@ -601,7 +591,7 @@ namespace AzToolsFramework
|
||||
virtual ResolveToolPathOutcome ResolveConfigToolsPath(const char* toolApplicationName) const = 0;
|
||||
|
||||
/**
|
||||
* LUMBERYARD INTERNAL USE ONLY.
|
||||
* Open 3D Engine Internal use only.
|
||||
*
|
||||
* Run a specific redo command separate from the undo/redo system.
|
||||
* In many cases before a modifcation on an entity takes place, it is first packaged into
|
||||
@@ -825,8 +815,6 @@ namespace AzToolsFramework
|
||||
/// Hide or show the circular dependency error when saving slices
|
||||
virtual void SetShowCircularDependencyError(const bool& /*showCircularDependencyError*/) {}
|
||||
|
||||
virtual void SetEditTool(const char* /*tool*/) {}
|
||||
|
||||
/// Launches the Lua editor and opens the specified (space separated) files.
|
||||
virtual void LaunchLuaEditor(const char* /*files*/) {}
|
||||
|
||||
|
||||
@@ -57,4 +57,4 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
#include "Application/moc_Ticker.cpp"
|
||||
#include "Application/moc_Ticker.cpp"
|
||||
|
||||
@@ -55,4 +55,4 @@ namespace AzToolsFramework
|
||||
float m_timeoutMS;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace AzToolsFramework
|
||||
namespace Internal
|
||||
{
|
||||
static const char* s_engineConfigFileName = "engine.json";
|
||||
static const char* s_engineConfigEngineVersionKey = "LumberyardVersion";
|
||||
static const char* s_engineConfigEngineVersionKey = "O3DEVersion";
|
||||
|
||||
static const char* s_startupLogWindow = "Startup";
|
||||
|
||||
@@ -224,112 +224,6 @@ namespace AzToolsFramework
|
||||
|
||||
} // Internal
|
||||
|
||||
#define AZ_MAX_ENGINE_VERSION_LEN 64
|
||||
// Private Implementation class to manage the engine root and version
|
||||
// Note: We are not using any AzCore classes because the ToolsApplication
|
||||
// initialization happens early on, before the Allocators get instantiated,
|
||||
// so we are using Qt privately instead
|
||||
class ToolsApplication::EngineConfigImpl
|
||||
{
|
||||
private:
|
||||
friend class ToolsApplication;
|
||||
|
||||
typedef QMap<QString, QString> EngineJsonMap;
|
||||
|
||||
EngineConfigImpl(const char* logWindow, const char* fileName)
|
||||
: m_logWindow(logWindow)
|
||||
, m_fileName(fileName)
|
||||
{
|
||||
m_engineRoot[0] = '\0';
|
||||
m_engineVersion[0] = '\0';
|
||||
}
|
||||
|
||||
char m_engineRoot[AZ_MAX_PATH_LEN];
|
||||
char m_engineVersion[AZ_MAX_ENGINE_VERSION_LEN];
|
||||
EngineJsonMap m_engineConfigMap;
|
||||
const char* m_logWindow;
|
||||
const char* m_fileName;
|
||||
|
||||
|
||||
// Read an engine configuration into a map of key/value pairs
|
||||
bool ReadEngineConfigIntoMap(QString engineJsonPath, EngineJsonMap& engineJsonMap)
|
||||
{
|
||||
QFile engineJsonFile(engineJsonPath);
|
||||
if (!engineJsonFile.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
AZ_Warning(m_logWindow, false, "Unable to open file '%s' in the current root directory", engineJsonPath.toUtf8().data());
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray engineJsonData = engineJsonFile.readAll();
|
||||
engineJsonFile.close();
|
||||
QJsonDocument engineJsonDoc(QJsonDocument::fromJson(engineJsonData));
|
||||
if (engineJsonDoc.isNull())
|
||||
{
|
||||
AZ_Warning(m_logWindow, false, "Unable to read file '%s' in the current root directory", engineJsonPath.toUtf8().data());
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonObject engineJsonRoot = engineJsonDoc.object();
|
||||
for (const QString& configKey : engineJsonRoot.keys())
|
||||
{
|
||||
QJsonValue configValue = engineJsonRoot[configKey];
|
||||
if (configValue.isString() || configValue.isDouble())
|
||||
{
|
||||
// Only map strings and numbers, ignore every other type
|
||||
engineJsonMap[configKey] = configValue.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning(m_logWindow, false, "Ignoring key '%s' from '%s', unsupported type.", configKey.toUtf8().data(), engineJsonPath.toUtf8().data());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Initialize the engine config object based on the current
|
||||
bool Initialize(const char* currentEngineRoot)
|
||||
{
|
||||
// Start with the app root as the engine root (legacy), but check to see if the engine root
|
||||
// is external to the app root
|
||||
azstrncpy(m_engineRoot, AZ_ARRAY_SIZE(m_engineRoot), currentEngineRoot, strlen(currentEngineRoot) + 1);
|
||||
|
||||
// From the appRoot, check and see if we can read any external engine reference in engine.json
|
||||
QString engineJsonFileName = QString(m_fileName);
|
||||
QString engineJsonFilePath = QDir(currentEngineRoot).absoluteFilePath(engineJsonFileName);
|
||||
|
||||
// From the appRoot, check and see if we can read any external engine reference in engine.json
|
||||
if (!QFile::exists(engineJsonFilePath))
|
||||
{
|
||||
AZ_Warning(m_logWindow, false, "Unable to find '%s' in the current app root directory.", m_fileName);
|
||||
return false;
|
||||
}
|
||||
if (!ReadEngineConfigIntoMap(engineJsonFilePath, m_engineConfigMap))
|
||||
{
|
||||
AZ_Warning(m_logWindow, false, "Defaulting root engine path to '%s'", currentEngineRoot);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read in the local engine version value
|
||||
auto localEngineVersionValue = m_engineConfigMap.find(QString(AzToolsFramework::Internal::s_engineConfigEngineVersionKey));
|
||||
QString localEngineVersion(localEngineVersionValue.value());
|
||||
azstrncpy(m_engineVersion, AZ_ARRAY_SIZE(m_engineVersion), localEngineVersion.toUtf8().data(), localEngineVersion.length() + 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* GetEngineRoot() const
|
||||
{
|
||||
return m_engineRoot;
|
||||
}
|
||||
|
||||
const char* GetEngineVersion() const
|
||||
{
|
||||
return m_engineVersion;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
ToolsApplication::ToolsApplication(int* argc, char*** argv)
|
||||
: AzFramework::Application(argc, argv)
|
||||
, m_selectionBounds(AZ::Aabb())
|
||||
@@ -339,7 +233,6 @@ namespace AzToolsFramework
|
||||
, m_isInIsolationMode(false)
|
||||
{
|
||||
ToolsApplicationRequests::Bus::Handler::BusConnect();
|
||||
m_engineConfigImpl.reset(new ToolsApplication::EngineConfigImpl(AzToolsFramework::Internal::s_startupLogWindow, AzToolsFramework::Internal::s_engineConfigFileName));
|
||||
|
||||
m_undoCache.RegisterToUndoCacheInterface();
|
||||
}
|
||||
@@ -391,7 +284,6 @@ namespace AzToolsFramework
|
||||
void ToolsApplication::Start(const Descriptor& descriptor, const StartupParameters& startupParameters/* = StartupParameters()*/)
|
||||
{
|
||||
Application::Start(descriptor, startupParameters);
|
||||
InitializeEngineConfig();
|
||||
|
||||
m_editorEntityManager.Start();
|
||||
|
||||
@@ -399,14 +291,6 @@ namespace AzToolsFramework
|
||||
AZ_Assert(m_editorEntityAPI, "ToolsApplication - Could not retrieve instance of EditorEntityAPI");
|
||||
}
|
||||
|
||||
void ToolsApplication::InitializeEngineConfig()
|
||||
{
|
||||
if (!m_engineConfigImpl->Initialize(GetEngineRoot()))
|
||||
{
|
||||
AZ_Warning(AzToolsFramework::Internal::s_startupLogWindow, false, "Defaulting engine root path to '%s'", GetEngineRoot());
|
||||
}
|
||||
}
|
||||
|
||||
void ToolsApplication::StartCommon(AZ::Entity* systemEntity)
|
||||
{
|
||||
Application::StartCommon(systemEntity);
|
||||
@@ -1832,16 +1716,6 @@ namespace AzToolsFramework
|
||||
return m_isInIsolationMode;
|
||||
}
|
||||
|
||||
const char* ToolsApplication::GetEngineRootPath() const
|
||||
{
|
||||
return m_engineConfigImpl->GetEngineRoot();
|
||||
}
|
||||
|
||||
const char* ToolsApplication::GetEngineVersion() const
|
||||
{
|
||||
return m_engineConfigImpl->GetEngineVersion();
|
||||
}
|
||||
|
||||
void ToolsApplication::CreateAndAddEntityFromComponentTags(const AZStd::vector<AZ::Crc32>& requiredTags, const char* entityName)
|
||||
{
|
||||
if (!entityName || !entityName[0])
|
||||
|
||||
@@ -150,12 +150,10 @@ namespace AzToolsFramework
|
||||
void EnterEditorIsolationMode() override;
|
||||
void ExitEditorIsolationMode() override;
|
||||
bool IsEditorInIsolationMode() override;
|
||||
const char* GetEngineRootPath() const override;
|
||||
const char* GetEngineVersion() const override;
|
||||
|
||||
void CreateAndAddEntityFromComponentTags(const AZStd::vector<AZ::Crc32>& requiredTags, const char* entityName) override;
|
||||
|
||||
/* LUMBERYARD INTERNAL USE ONLY. */
|
||||
/* Open 3D Engine INTERNAL USE ONLY. */
|
||||
void RunRedoSeparately(UndoSystem::URSequencePoint* redoCommand) override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -174,7 +172,6 @@ namespace AzToolsFramework
|
||||
|
||||
void CreateUndosForDirtyEntities();
|
||||
void ConsistencyCheckUndoCache();
|
||||
void InitializeEngineConfig();
|
||||
AZ::Aabb m_selectionBounds;
|
||||
EntityIdList m_selectedEntities;
|
||||
EntityIdList m_highlightedEntities;
|
||||
@@ -186,9 +183,6 @@ namespace AzToolsFramework
|
||||
bool m_isInIsolationMode;
|
||||
EntityIdSet m_isolatedEntityIdSet;
|
||||
|
||||
class EngineConfigImpl;
|
||||
AZStd::unique_ptr<EngineConfigImpl> m_engineConfigImpl;
|
||||
|
||||
EditorEntityAPI* m_editorEntityAPI = nullptr;
|
||||
|
||||
EditorEntityManager m_editorEntityManager;
|
||||
|
||||
@@ -255,10 +255,8 @@ namespace AzToolsFramework::AssetUtils
|
||||
return configFiles;
|
||||
}
|
||||
|
||||
bool UpdateFilePathToCorrectCase(const QString& root, QString& relativePathFromRoot)
|
||||
bool UpdateFilePathToCorrectCase(AZStd::string_view rootPath, AZStd::string& relPathFromRoot)
|
||||
{
|
||||
AZStd::string rootPath(root.toUtf8().data());
|
||||
AZStd::string relPathFromRoot(relativePathFromRoot.toUtf8().data());
|
||||
AZ::StringFunc::Path::Normalize(relPathFromRoot);
|
||||
AZStd::vector<AZStd::string> tokens;
|
||||
AZ::StringFunc::Tokenize(relPathFromRoot.c_str(), tokens, AZ_CORRECT_FILESYSTEM_SEPARATOR_STRING);
|
||||
@@ -321,7 +319,6 @@ namespace AzToolsFramework::AssetUtils
|
||||
{
|
||||
relPathFromRoot.clear();
|
||||
AZ::StringFunc::Join(relPathFromRoot, tokens.begin(), tokens.end(), AZ_CORRECT_FILESYSTEM_SEPARATOR_STRING);
|
||||
relativePathFromRoot = relPathFromRoot.c_str();
|
||||
}
|
||||
|
||||
return success;
|
||||
|
||||
@@ -52,5 +52,5 @@ namespace AzToolsFramework::AssetUtils
|
||||
//! which will be normalized and updated to be correct casing.
|
||||
//! @return if such a file does NOT exist, it returns FALSE, else returns TRUE.
|
||||
//! @note A very expensive function! Call sparingly.
|
||||
bool UpdateFilePathToCorrectCase(const QString& root, QString& relativePathFromRoot);
|
||||
bool UpdateFilePathToCorrectCase(AZStd::string_view root, AZStd::string& relativePathFromRoot);
|
||||
} //namespace AzToolsFramework::AssetUtils
|
||||
|
||||
@@ -165,4 +165,4 @@ namespace AzToolsFramework
|
||||
AZ::Data::AssetId m_assetId;
|
||||
};
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -75,4 +75,4 @@ namespace AzToolsFramework
|
||||
|
||||
};
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
#include <AzToolsFramework/AssetBrowser/AssetPicker/AssetPickerDialog.h>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4244, "-Wunknown-warning-option") // disable warnings spawned by QT
|
||||
#include "AssetBrowser/AssetPicker/ui_AssetPickerDialog.h"
|
||||
#include <AzToolsFramework/AssetBrowser/AssetPicker/ui_AssetPickerDialog.h>
|
||||
#include <QPushButton>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QKeyEvent>
|
||||
|
||||
@@ -76,4 +76,4 @@ namespace AzToolsFramework
|
||||
QString m_title;
|
||||
};
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -283,4 +283,4 @@ namespace AzToolsFramework
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
#include "AssetBrowser/Entries/moc_AssetBrowserEntry.cpp"
|
||||
#include "AssetBrowser/Entries/moc_AssetBrowserEntry.cpp"
|
||||
|
||||
+1
-1
@@ -69,4 +69,4 @@ namespace AzToolsFramework
|
||||
m_absolutePathToFileId.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -55,4 +55,4 @@ namespace AzToolsFramework
|
||||
AZ_DISABLE_COPY_MOVE(FolderAssetBrowserEntry);
|
||||
};
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -63,4 +63,4 @@ namespace AzToolsFramework
|
||||
AZ_DISABLE_COPY_MOVE(ProductAssetBrowserEntry);
|
||||
};
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -95,4 +95,4 @@ namespace AzToolsFramework
|
||||
bool m_isInitialUpdate = false;
|
||||
};
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -80,4 +80,4 @@ namespace AzToolsFramework
|
||||
AZ_DISABLE_COPY_MOVE(SourceAssetBrowserEntry);
|
||||
};
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@
|
||||
// 4251: class needs to have dll-interface to be used by clients of class
|
||||
// 4800: forcing value to bool 'true' or 'false' (performance warning)
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option")
|
||||
#include "AssetBrowser/Previewer/ui_EmptyPreviewer.h"
|
||||
#include <AzToolsFramework/AssetBrowser/Previewer/ui_EmptyPreviewer.h>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
namespace AzToolsFramework
|
||||
@@ -45,4 +45,4 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
#include <AssetBrowser/Previewer/moc_EmptyPreviewer.cpp>
|
||||
#include <AssetBrowser/Previewer/moc_EmptyPreviewer.cpp>
|
||||
|
||||
+1
-1
@@ -47,4 +47,4 @@ namespace AzToolsFramework
|
||||
QScopedPointer<Ui::EmptyPreviewerClass> m_ui;
|
||||
};
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -23,4 +23,4 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
#include <AssetBrowser/Previewer/moc_Previewer.cpp>
|
||||
#include <AssetBrowser/Previewer/moc_Previewer.cpp>
|
||||
|
||||
+1
-1
@@ -44,4 +44,4 @@ namespace AzToolsFramework
|
||||
|
||||
using PreviewerRequestBus = AZ::EBus<PreviewerRequests>;
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -34,4 +34,4 @@ namespace AzToolsFramework
|
||||
virtual const QString& GetName() const = 0;
|
||||
};
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -613,4 +613,4 @@ namespace AzToolsFramework
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
#include "AssetBrowser/Search/moc_Filter.cpp"
|
||||
#include "AssetBrowser/Search/moc_Filter.cpp"
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
#include <AzQtComponents/Components/ExtendedLabel.h>
|
||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: class 'QFlags<Qt::AlignmentFlag>' needs to have dll-interface to be used by clients of class 'QLayoutItem'
|
||||
#include <AssetBrowser/Search/ui_FilterByWidget.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Search/ui_FilterByWidget.h>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
#include <AzToolsFramework/AssetBrowser/Search/FilterByWidget.h>
|
||||
|
||||
@@ -39,4 +39,4 @@ namespace AzToolsFramework
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
#include "AssetBrowser/Search/moc_FilterByWidget.cpp"
|
||||
#include "AssetBrowser/Search/moc_FilterByWidget.cpp"
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@
|
||||
#include <AzToolsFramework/AssetBrowser/Search/FilterByWidget.h>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: 'QLayoutItem::align': class 'QFlags<Qt::AlignmentFlag>' needs to have dll-interface to be used by clients of class 'QLayoutItem'
|
||||
#include <AssetBrowser/Search/ui_SearchAssetTypeSelectorWidget.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Search/ui_SearchAssetTypeSelectorWidget.h>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
#include <QPushButton>
|
||||
@@ -154,4 +154,4 @@ namespace AzToolsFramework
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
#include "AssetBrowser/Search/moc_SearchAssetTypeSelectorWidget.cpp"
|
||||
#include "AssetBrowser/Search/moc_SearchAssetTypeSelectorWidget.cpp"
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@
|
||||
|
||||
#include "SearchParametersWidget.h"
|
||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: 'QLayoutItem::align': class 'QFlags<Qt::AlignmentFlag>' needs to have dll-interface to be used by clients of class 'QLayoutItem'
|
||||
#include "AssetBrowser/Search/ui_SearchParametersWidget.h"
|
||||
#include <AzToolsFramework/AssetBrowser/Search/ui_SearchParametersWidget.h>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
#include <AzQtComponents/Components/ExtendedLabel.h>
|
||||
|
||||
@@ -68,4 +68,4 @@ namespace AzToolsFramework
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
#include "AssetBrowser/Search/moc_SearchParametersWidget.cpp"
|
||||
#include "AssetBrowser/Search/moc_SearchParametersWidget.cpp"
|
||||
|
||||
@@ -170,6 +170,15 @@ namespace AzToolsFramework
|
||||
return m_filter;
|
||||
}
|
||||
|
||||
QSharedPointer<CompositeFilter> SearchWidget::GetStringFilter() const
|
||||
{
|
||||
return m_stringFilter;
|
||||
}
|
||||
|
||||
QSharedPointer<CompositeFilter> SearchWidget::GetTypesFilter() const
|
||||
{
|
||||
return m_typesFilter;
|
||||
}
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
|
||||
@@ -39,6 +39,10 @@ namespace AzToolsFramework
|
||||
|
||||
QSharedPointer<CompositeFilter> GetFilter() const;
|
||||
|
||||
QSharedPointer<CompositeFilter> GetStringFilter() const;
|
||||
|
||||
QSharedPointer<CompositeFilter> GetTypesFilter() const;
|
||||
|
||||
QString GetFilterString() const { return textFilter(); }
|
||||
void ClearStringFilter() { ClearTextFilter(); }
|
||||
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 948 B After Width: | Height: | Size: 949 B |
@@ -8,4 +8,4 @@
|
||||
<rect id="Icon-Background" x="0" y="0" width="24" height="24"></rect>
|
||||
<path d="M20.9694824,19.6604004 L16.3757324,15.0666504 C17.4069824,13.7541504 17.9694824,12.1604004 17.9694824,10.4729004 C17.9694824,6.34790039 14.5944824,2.97290039 10.4694824,2.97290039 C6.34448242,2.97290039 2.96948242,6.34790039 2.96948242,10.4729004 C2.96948242,14.5979004 6.34448242,17.9729004 10.4694824,17.9729004 C12.1569824,17.9729004 13.7507324,17.4104004 15.0632324,16.3791504 L19.6569824,20.9729004 L20.9694824,19.6604004 Z M10.4694824,16.0979004 C7.37573242,16.0979004 4.84448242,13.5666504 4.84448242,10.4729004 C4.84448242,7.37915039 7.37573242,4.84790039 10.4694824,4.84790039 C13.5632324,4.84790039 16.0944824,7.37915039 16.0944824,10.4729004 C16.0944824,13.5666504 13.5632324,16.0979004 10.4694824,16.0979004 Z" id="Shape" fill="#E9E9E9" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
+1
-1
@@ -54,7 +54,7 @@ namespace AzToolsFramework
|
||||
//! Set unique asset browser name, used to persist tree expansion states
|
||||
void SetName(const QString& name);
|
||||
|
||||
// LUMBERYARD_DEPRECATED
|
||||
// O3DE_DEPRECATED
|
||||
void LoadState(const QString& name);
|
||||
void SaveState() const;
|
||||
|
||||
|
||||
+5
-2
@@ -139,8 +139,11 @@ namespace AzToolsFramework
|
||||
}
|
||||
else
|
||||
{
|
||||
QPixmap pixmap = thumbnail->GetPixmap(size);
|
||||
painter->drawPixmap(point.x(), point.y(), size.width(), size.height(), pixmap);
|
||||
// Scaling and centering pixmap within bounds to preserve aspect ratio
|
||||
const QPixmap pixmap = thumbnail->GetPixmap(size).scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
const QSize sizeDelta = size - pixmap.size();
|
||||
const QPoint pointDelta = QPoint(sizeDelta.width() / 2, sizeDelta.height() / 2);
|
||||
painter->drawPixmap(point + pointDelta, pixmap);
|
||||
}
|
||||
return m_iconSize;
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
#include <AssetEditor/AssetEditorBus.h>
|
||||
#include <AssetEditor/AssetEditorHeader.h>
|
||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 'QLayoutItem::align': class 'QFlags<Qt::AlignmentFlag>' needs to have dll-interface to be used by clients of class 'QLayoutItem'
|
||||
#include <AssetEditor/ui_AssetEditorToolbar.h>
|
||||
#include <AzToolsFramework/AssetEditor/ui_AssetEditorToolbar.h>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
#include <AssetEditor/ui_AssetEditorStatusBar.h>
|
||||
#include <AzToolsFramework/AssetEditor/ui_AssetEditorStatusBar.h>
|
||||
|
||||
#include <AssetBrowser/AssetSelectionModel.h>
|
||||
|
||||
@@ -256,6 +256,8 @@ namespace AzToolsFramework
|
||||
|
||||
m_userSettings = AZ::UserSettings::CreateFind<AssetEditorWidgetUserSettings>(k_assetEditorWidgetSettings, AZ::UserSettings::CT_LOCAL);
|
||||
|
||||
UpdateRecentFileListState();
|
||||
|
||||
QObject::connect(m_recentFileMenu, &QMenu::aboutToShow, this, &AssetEditorWidget::PopulateRecentMenu);
|
||||
}
|
||||
|
||||
@@ -952,7 +954,8 @@ namespace AzToolsFramework
|
||||
|
||||
void AssetEditorWidget::AddRecentPath(const AZStd::string& recentPath)
|
||||
{
|
||||
m_userSettings->AddRecentPath(recentPath);
|
||||
m_userSettings->AddRecentPath(recentPath);
|
||||
UpdateRecentFileListState();
|
||||
}
|
||||
|
||||
void AssetEditorWidget::PopulateRecentMenu()
|
||||
@@ -989,6 +992,21 @@ namespace AzToolsFramework
|
||||
m_saveAsAssetAction->setEnabled(true);
|
||||
}
|
||||
|
||||
void AssetEditorWidget::UpdateRecentFileListState()
|
||||
{
|
||||
if (m_recentFileMenu)
|
||||
{
|
||||
if (!m_userSettings || m_userSettings->m_recentPaths.empty())
|
||||
{
|
||||
m_recentFileMenu->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_recentFileMenu->setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AssetEditor
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
|
||||
@@ -122,6 +122,8 @@ namespace AzToolsFramework
|
||||
void OnCatalogAssetAdded(const AZ::Data::AssetId& assetId) override;
|
||||
void OnCatalogAssetRemoved(const AZ::Data::AssetId& assetId, const AZ::Data::AssetInfo& assetInfo) override;
|
||||
|
||||
void UpdateRecentFileListState();
|
||||
|
||||
private:
|
||||
void DirtyAsset();
|
||||
|
||||
|
||||
@@ -25,4 +25,4 @@ namespace AzToolsFramework
|
||||
AzToolsFrameworkModule();
|
||||
~AzToolsFrameworkModule() override = default;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,4 +72,4 @@ namespace AzToolsFramework
|
||||
m_componentModeBuilders, m_transition);
|
||||
}
|
||||
} // namespace ComponentModeFramework
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -50,4 +50,4 @@ namespace AzToolsFramework
|
||||
Transition m_transition; ///< Entering/Leaving ComponentMode.
|
||||
};
|
||||
} // namespace ComponentModeFramework
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -105,4 +105,4 @@ namespace AzToolsFramework
|
||||
return PivotHasTranslationOverride(pivotOverride) || PivotHasOrientationOverride(pivotOverride);
|
||||
}
|
||||
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -103,4 +103,4 @@ namespace AzToolsFramework
|
||||
bool PivotHasOrientationOverride(AZ::u8 pivotOverride);
|
||||
bool PivotHasTransformOverride(AZ::u8 pivotOverride);
|
||||
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+10
-3
@@ -191,10 +191,17 @@ namespace AzToolsFramework
|
||||
{
|
||||
if (componentClass->m_editData->m_name == componentTypeNames[i])
|
||||
{
|
||||
// Although it is rare, it can happen that two (or more) components can have the same name.
|
||||
// We should only count the first occurrence, so that none of the names in componentTypeNames
|
||||
// get skipped, but whichever component type that is encountered last will be the one
|
||||
// that is captured in order to preserve the pre-existing behavior.
|
||||
if (foundTypeIds[i].IsNull())
|
||||
{
|
||||
++counter;
|
||||
}
|
||||
|
||||
foundTypeIds[i] = componentClass->m_typeId;
|
||||
++counter;
|
||||
//Although it is rare, it can happen that two components can have the same name.
|
||||
//We will capture only the first occurrence.
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -32,4 +32,4 @@ namespace AzToolsFramework
|
||||
{
|
||||
m_boxEdit.UpdateManipulators();
|
||||
}
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -40,4 +40,4 @@ namespace AzToolsFramework
|
||||
private:
|
||||
BoxViewportEdit m_boxEdit;
|
||||
};
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -183,4 +183,4 @@ namespace AzToolsFramework
|
||||
} // Debug
|
||||
} // AzToolsFramework
|
||||
|
||||
#endif // AZ_ENABLE_TRACE_CONTEXT
|
||||
#endif // AZ_ENABLE_TRACE_CONTEXT
|
||||
|
||||
+1
-1
@@ -130,7 +130,7 @@ namespace AzToolsFramework
|
||||
int written = uuid.ToString(buffer, aznumeric_caster(bufferSize), false);
|
||||
if (written > 0)
|
||||
{
|
||||
if (bufferSize - written > 0)
|
||||
if (bufferSize > written)
|
||||
{
|
||||
buffer[written - 1] = '\n';
|
||||
buffer[written] = 0;
|
||||
|
||||
+1
-1
@@ -20,4 +20,4 @@ namespace AzToolsFramework
|
||||
return Print(buffer, size, stack, printUuids, startIndex);
|
||||
}
|
||||
} // Debug
|
||||
} // AzToolsFramework
|
||||
} // AzToolsFramework
|
||||
|
||||
+9
-2
@@ -453,6 +453,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
loadedSuccessfully = static_cast<PrefabEditorEntityOwnershipService*>(m_entityOwnershipService.get())->LoadFromStream(
|
||||
stream, AZStd::string_view(levelPakFile.toUtf8(), levelPakFile.size()) );
|
||||
|
||||
}
|
||||
|
||||
LoadFromStreamComplete(loadedSuccessfully);
|
||||
@@ -490,6 +491,14 @@ namespace AzToolsFramework
|
||||
|
||||
EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::OnStartPlayInEditorBegin);
|
||||
|
||||
//cache the current selected entities.
|
||||
ToolsApplicationRequests::Bus::BroadcastResult(m_selectedBeforeStartingGame, &ToolsApplicationRequests::GetSelectedEntities);
|
||||
//deselect entities if selected when entering game mode before deactivating the entities in StartPlayInEditor(...)
|
||||
if (!m_selectedBeforeStartingGame.empty())
|
||||
{
|
||||
ToolsApplicationRequests::Bus::Broadcast(&ToolsApplicationRequests::MarkEntitiesDeselected, m_selectedBeforeStartingGame);
|
||||
}
|
||||
|
||||
if (m_isLegacySliceService)
|
||||
{
|
||||
SliceEditorEntityOwnershipService* editorEntityOwnershipService =
|
||||
@@ -506,8 +515,6 @@ namespace AzToolsFramework
|
||||
|
||||
m_isRunningGame = true;
|
||||
|
||||
ToolsApplicationRequests::Bus::BroadcastResult(m_selectedBeforeStartingGame, &ToolsApplicationRequests::GetSelectedEntities);
|
||||
|
||||
EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::OnStartPlayInEditor);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -37,4 +37,4 @@ namespace AzToolsFramework
|
||||
|
||||
using EditorEntityContextPickingRequestBus = AZ::EBus<EditorEntityContextPickingRequests>;
|
||||
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -36,4 +36,4 @@ namespace AzToolsFramework
|
||||
void OnSliceEntitiesLoaded(const AZStd::vector<AZ::Entity*>& entities) override;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -136,6 +136,48 @@ namespace AzToolsFramework
|
||||
return entity->GetName();
|
||||
}
|
||||
|
||||
EntityList EntityIdListToEntityList(const EntityIdList& inputEntityIds)
|
||||
{
|
||||
EntityList entities;
|
||||
entities.reserve(inputEntityIds.size());
|
||||
|
||||
for (AZ::EntityId entityId : inputEntityIds)
|
||||
{
|
||||
if (!entityId.IsValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto entity = GetEntityById(entityId))
|
||||
{
|
||||
entities.emplace_back(entity);
|
||||
}
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
EntityList EntityIdSetToEntityList(const EntityIdSet& inputEntityIds)
|
||||
{
|
||||
EntityList entities;
|
||||
entities.reserve(inputEntityIds.size());
|
||||
|
||||
for (AZ::EntityId entityId : inputEntityIds)
|
||||
{
|
||||
if (!entityId.IsValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto entity = GetEntityById(entityId))
|
||||
{
|
||||
entities.emplace_back(entity);
|
||||
}
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
void GetAllComponentsForEntity(const AZ::Entity* entity, AZ::Entity::ComponentArrayType& componentsOnEntity)
|
||||
{
|
||||
if (entity)
|
||||
@@ -1068,6 +1110,45 @@ namespace AzToolsFramework
|
||||
return !allEntityClonesContainer.m_entities.empty();
|
||||
}
|
||||
|
||||
EntityIdSet GetCulledEntityHierarchy(const EntityIdList& entities)
|
||||
{
|
||||
EntityIdSet culledEntities;
|
||||
|
||||
for (const AZ::EntityId& entityId : entities)
|
||||
{
|
||||
bool selectionIncludesTransformHeritage = false;
|
||||
AZ::EntityId parentEntityId = entityId;
|
||||
do
|
||||
{
|
||||
AZ::EntityId nextParentId;
|
||||
AZ::TransformBus::EventResult(
|
||||
/*result*/ nextParentId,
|
||||
/*address*/ parentEntityId,
|
||||
&AZ::TransformBus::Events::GetParentId);
|
||||
parentEntityId = nextParentId;
|
||||
if (!parentEntityId.IsValid())
|
||||
{
|
||||
break;
|
||||
}
|
||||
for (const AZ::EntityId& parentCheck : entities)
|
||||
{
|
||||
if (parentCheck == parentEntityId)
|
||||
{
|
||||
selectionIncludesTransformHeritage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (parentEntityId.IsValid() && !selectionIncludesTransformHeritage);
|
||||
|
||||
if (!selectionIncludesTransformHeritage)
|
||||
{
|
||||
culledEntities.insert(entityId);
|
||||
}
|
||||
}
|
||||
|
||||
return culledEntities;
|
||||
}
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
void CloneSliceEntitiesAndChildren(
|
||||
|
||||
@@ -47,6 +47,9 @@ namespace AzToolsFramework
|
||||
|
||||
AZStd::string GetEntityName(const AZ::EntityId& entityId, const AZStd::string_view& nameOverride = {});
|
||||
|
||||
EntityList EntityIdListToEntityList(const EntityIdList& inputEntityIds);
|
||||
EntityList EntityIdSetToEntityList(const EntityIdSet& inputEntityIds);
|
||||
|
||||
template <typename... ComponentTypes>
|
||||
struct AddComponents
|
||||
{
|
||||
@@ -202,4 +205,8 @@ namespace AzToolsFramework
|
||||
/// Wrap EBus SetSelectedEntities call.
|
||||
void SelectEntities(const AzToolsFramework::EntityIdList& entities);
|
||||
|
||||
/// Return a set of entities, culling any that have an ancestor in the list.
|
||||
/// e.g. This is useful for getting a concise set of entities that need to be duplicated.
|
||||
EntityIdSet GetCulledEntityHierarchy(const EntityIdList& entities);
|
||||
|
||||
}; // namespace AzToolsFramework
|
||||
|
||||
@@ -707,7 +707,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
QMessageBox::warning(AzToolsFramework::GetActiveWindow(),
|
||||
QStringLiteral("Can't instantiate the selected slice"),
|
||||
QString("The slice may contain UI elements that can't be instantiated in the main Lumberyard editor. "
|
||||
QString("The slice may contain UI elements that can't be instantiated in the main Open 3D Engine editor. "
|
||||
"Use the UI Editor to instantiate this slice or select another one."),
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
|
||||
@@ -25,4 +25,4 @@ namespace AzToolsFramework
|
||||
virtual void RemoveFromChildrenWithOverrides(const EntityIdList& parentEntityIds, const AZ::EntityId& entityId) = 0;
|
||||
};
|
||||
using EditorEntityModelRequestBus = AZ::EBus<EditorEntityModelRequests>;
|
||||
}
|
||||
}
|
||||
|
||||
+9
-1
@@ -31,11 +31,19 @@ namespace AzToolsFramework
|
||||
//! /param entities The entities to put under the new prefab.
|
||||
//! /param nestedPrefabInstances The nested prefab instances to put under the new prefab.
|
||||
//! /param filePath The filepath corresponding to the prefab file to be created.
|
||||
//! /param instanceToParentUnder The instance under which the newly created prefab instance is parented under.
|
||||
//! /param instanceToParentUnder The instance the newly created prefab instance is parented under.
|
||||
//! /return The optional reference to the prefab created.
|
||||
virtual Prefab::InstanceOptionalReference CreatePrefab(
|
||||
const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Prefab::Instance>>&& nestedPrefabInstances,
|
||||
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder = AZStd::nullopt) = 0;
|
||||
|
||||
//! Instantiate the prefab file provided.
|
||||
//! /param filePath The filepath for the prefab file the instance should be created from.
|
||||
//! /param instanceToParentUnder The instance the newly instantiated prefab instance is parented under.
|
||||
//! /return The optional reference to the prefab instance.
|
||||
virtual Prefab::InstanceOptionalReference InstantiatePrefab(
|
||||
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder = AZStd::nullopt) = 0;
|
||||
|
||||
virtual Prefab::InstanceOptionalReference GetRootPrefabInstance() = 0;
|
||||
|
||||
virtual bool LoadFromStream(AZ::IO::GenericStream& stream, AZStd::string_view filename) = 0;
|
||||
|
||||
+80
-7
@@ -11,16 +11,20 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Script/ScriptSystemBus.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzFramework/Entity/GameEntityContextBus.h>
|
||||
#include <AzFramework/Spawnable/RootSpawnableInterface.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h>
|
||||
#include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabLoader.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabUndoHelpers.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
@@ -91,23 +95,48 @@ namespace AzToolsFramework
|
||||
m_prefabSystemComponent->RemoveTemplate(templateId);
|
||||
}
|
||||
m_rootInstance->Reset();
|
||||
m_rootInstance->SetContainerEntityName("Level");
|
||||
|
||||
AzFramework::EntityOwnershipServiceNotificationBus::Event(
|
||||
m_entityContextId, &AzFramework::EntityOwnershipServiceNotificationBus::Events::OnEntityOwnershipServiceReset);
|
||||
}
|
||||
|
||||
void PrefabEditorEntityOwnershipService::AddEntity(AZ::Entity* entity)
|
||||
{
|
||||
AZ_Assert(IsInitialized(), "Tried to add an entity without initializing the Entity Ownership Service");
|
||||
ScopedUndoBatch undoBatch("Undo adding entity");
|
||||
Prefab::PrefabDom instanceDomBeforeUpdate;
|
||||
Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, instanceDomBeforeUpdate);
|
||||
|
||||
m_rootInstance->AddEntity(*entity);
|
||||
HandleEntitiesAdded({ entity });
|
||||
AZ::TransformBus::Event(entity->GetId(), &AZ::TransformInterface::SetParent, m_rootInstance->m_containerEntity->GetId());
|
||||
|
||||
Prefab::PrefabUndoHelpers::UpdatePrefabInstance(
|
||||
*m_rootInstance, "Undo adding entity", instanceDomBeforeUpdate, undoBatch.GetUndoBatch());
|
||||
}
|
||||
|
||||
void PrefabEditorEntityOwnershipService::AddEntities(const EntityList& entities)
|
||||
{
|
||||
AZ_Assert(IsInitialized(), "Tried to add entities without initializing the Entity Ownership Service");
|
||||
ScopedUndoBatch undoBatch("Undo adding entities");
|
||||
Prefab::PrefabDom instanceDomBeforeUpdate;
|
||||
Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, instanceDomBeforeUpdate);
|
||||
|
||||
for (AZ::Entity* entity : entities)
|
||||
{
|
||||
m_rootInstance->AddEntity(*entity);
|
||||
}
|
||||
|
||||
HandleEntitiesAdded(entities);
|
||||
|
||||
for (AZ::Entity* entity : entities)
|
||||
{
|
||||
AZ::TransformBus::Event(entity->GetId(), &AZ::TransformInterface::SetParent, m_rootInstance->m_containerEntity->GetId());
|
||||
}
|
||||
|
||||
Prefab::PrefabUndoHelpers::UpdatePrefabInstance(
|
||||
*m_rootInstance, "Undo adding entities", instanceDomBeforeUpdate, undoBatch.GetUndoBatch());
|
||||
}
|
||||
|
||||
bool PrefabEditorEntityOwnershipService::DestroyEntity(AZ::Entity* entity)
|
||||
@@ -171,7 +200,9 @@ namespace AzToolsFramework
|
||||
|
||||
m_rootInstance->SetTemplateId(templateId);
|
||||
m_rootInstance->SetTemplateSourcePath(m_loaderInterface->GetRelativePathToProject(filename));
|
||||
m_rootInstance->SetContainerEntityName("Level");
|
||||
m_prefabSystemComponent->PropagateTemplateChanges(templateId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -249,20 +280,51 @@ namespace AzToolsFramework
|
||||
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder)
|
||||
{
|
||||
AZStd::unique_ptr<Prefab::Instance> createdPrefabInstance =
|
||||
m_prefabSystemComponent->CreatePrefab(entities, AZStd::move(nestedPrefabInstances), filePath);
|
||||
|
||||
if (!instanceToParentUnder)
|
||||
{
|
||||
instanceToParentUnder = *m_rootInstance;
|
||||
}
|
||||
m_prefabSystemComponent->CreatePrefab(entities, AZStd::move(nestedPrefabInstances), filePath, nullptr, false);
|
||||
|
||||
if (createdPrefabInstance)
|
||||
{
|
||||
if (!instanceToParentUnder)
|
||||
{
|
||||
instanceToParentUnder = *m_rootInstance;
|
||||
}
|
||||
|
||||
Prefab::Instance& addedInstance = instanceToParentUnder->get().AddInstance(AZStd::move(createdPrefabInstance));
|
||||
AZ::Entity* containerEntity = addedInstance.m_containerEntity.get();
|
||||
containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent());
|
||||
HandleEntitiesAdded({containerEntity});
|
||||
HandleEntitiesAdded(entities);
|
||||
|
||||
// Update the template of the instance since we modified the entities of the instance by calling HandleEntitiesAdded.
|
||||
Prefab::PrefabDom serializedInstance;
|
||||
if (Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(addedInstance, serializedInstance))
|
||||
{
|
||||
m_prefabSystemComponent->UpdatePrefabTemplate(addedInstance.GetTemplateId(), serializedInstance);
|
||||
}
|
||||
|
||||
return addedInstance;
|
||||
}
|
||||
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
Prefab::InstanceOptionalReference PrefabEditorEntityOwnershipService::InstantiatePrefab(
|
||||
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder)
|
||||
{
|
||||
AZStd::unique_ptr<Prefab::Instance> createdPrefabInstance = m_prefabSystemComponent->InstantiatePrefab(filePath);
|
||||
|
||||
if (createdPrefabInstance)
|
||||
{
|
||||
if (!instanceToParentUnder)
|
||||
{
|
||||
instanceToParentUnder = *m_rootInstance;
|
||||
}
|
||||
|
||||
Prefab::Instance& addedInstance = instanceToParentUnder->get().AddInstance(AZStd::move(createdPrefabInstance));
|
||||
HandleEntitiesAdded({addedInstance.m_containerEntity.get()});
|
||||
return addedInstance;
|
||||
}
|
||||
HandleEntitiesAdded(entities);
|
||||
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
@@ -295,6 +357,9 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabEditorEntityOwnershipService::StartPlayInEditor()
|
||||
{
|
||||
// This is a workaround until the replacement for GameEntityContext is done
|
||||
AzFramework::GameEntityContextEventBus::Broadcast(&AzFramework::GameEntityContextEventBus::Events::OnPreGameEntitiesStarted);
|
||||
|
||||
if (m_rootInstance && !m_playInEditorData.m_isEnabled)
|
||||
{
|
||||
// Construct the runtime entities and products
|
||||
@@ -339,11 +404,16 @@ namespace AzToolsFramework
|
||||
m_playInEditorData.m_assets.emplace_back(product.ReleaseAsset().release(), AZ::Data::AssetLoadBehavior::Default);
|
||||
}
|
||||
|
||||
|
||||
if (rootSpawnableIndex != NoRootSpawnable)
|
||||
{
|
||||
m_playInEditorData.m_entities.Reset(m_playInEditorData.m_assets[rootSpawnableIndex]);
|
||||
m_playInEditorData.m_entities.SpawnAllEntities();
|
||||
}
|
||||
|
||||
// This is a workaround until the replacement for GameEntityContext is done
|
||||
AzFramework::GameEntityContextEventBus::Broadcast(
|
||||
&AzFramework::GameEntityContextEventBus::Events::OnGameEntitiesStarted);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -402,6 +472,9 @@ namespace AzToolsFramework
|
||||
AZ::ScriptSystemRequestBus::Broadcast(&AZ::ScriptSystemRequests::GarbageCollect);
|
||||
});
|
||||
m_playInEditorData.m_entities.Clear();
|
||||
|
||||
// This is a workaround until the replacement for GameEntityContext is done
|
||||
AzFramework::GameEntityContextEventBus::Broadcast(&AzFramework::GameEntityContextEventBus::Events::OnGameEntitiesReset);
|
||||
}
|
||||
|
||||
m_playInEditorData.m_isEnabled = false;
|
||||
|
||||
+4
-1
@@ -186,11 +186,14 @@ namespace AzToolsFramework
|
||||
PlayInEditorData m_playInEditorData;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PrefabSystemComponentInterface interface implementation
|
||||
// PrefabEditorEntityOwnershipInterface implementation
|
||||
Prefab::InstanceOptionalReference CreatePrefab(
|
||||
const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Prefab::Instance>>&& nestedPrefabInstances,
|
||||
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder) override;
|
||||
|
||||
Prefab::InstanceOptionalReference InstantiatePrefab(
|
||||
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder) override;
|
||||
|
||||
Prefab::InstanceOptionalReference GetRootPrefabInstance() override;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
+1
-1
@@ -48,4 +48,4 @@ namespace AzToolsFramework
|
||||
|
||||
/// Type to inherit to implement BoxManipulatorRequests
|
||||
using BoxManipulatorRequestBus = AZ::EBus<BoxManipulatorRequests>;
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace AzToolsFramework
|
||||
const AzFramework::CameraState& cameraState,
|
||||
const ViewportInteraction::MouseInteraction& mouseInteraction);
|
||||
|
||||
// LUMBERYARD_DEPRECATED(LY-117150)
|
||||
// O3DE_DEPRECATED(LY-117150)
|
||||
/// Check if the modifier key state has changed - if so we may need to refresh
|
||||
/// certain manipulator bounds.
|
||||
AZ_DEPRECATED(
|
||||
|
||||
+1
-1
@@ -40,4 +40,4 @@ namespace AzToolsFramework
|
||||
|
||||
using MaterialBrowserRequestBus = AZ::EBus<MaterialBrowserRequests>;
|
||||
} // namespace MaterialBrowser
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -38,4 +38,4 @@ namespace AzToolsFramework
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
|
||||
};
|
||||
} // namespace MaterialBrowser
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -216,4 +216,4 @@ namespace AzToolsFramework
|
||||
///< intersecting point.
|
||||
};
|
||||
} // namespace Picking
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -52,4 +52,4 @@ namespace AzToolsFramework
|
||||
RegisteredBoundId m_nextBoundId = RegisteredBoundId(1); ///< Next bound id to use when a bound is registered.
|
||||
};
|
||||
} // namespace Picking
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -56,16 +56,6 @@ namespace AzToolsFramework
|
||||
|
||||
void EditorPrefabComponent::Activate()
|
||||
{
|
||||
PrefabPublicInterface* prefabPublicInterface = AZ::Interface<PrefabPublicInterface>::Get();
|
||||
if (prefabPublicInterface && prefabPublicInterface->IsLevelInstanceContainerEntity(GetEntityId()))
|
||||
{
|
||||
EntityOutlinerWidgetInterface* entityOutlinerWidgetInterface = AZ::Interface<EntityOutlinerWidgetInterface>::Get();
|
||||
if (entityOutlinerWidgetInterface)
|
||||
{
|
||||
entityOutlinerWidgetInterface->SetRootEntity(GetEntityId());
|
||||
}
|
||||
}
|
||||
|
||||
PrefabInstanceContainerNotificationBus::Broadcast(
|
||||
&PrefabInstanceContainerNotifications::OnPrefabComponentActivate, GetEntityId());
|
||||
}
|
||||
|
||||
@@ -123,7 +123,11 @@ namespace AzToolsFramework
|
||||
void Instance::SetTemplateSourcePath(AZ::IO::PathView sourcePath)
|
||||
{
|
||||
m_templateSourcePath = sourcePath;
|
||||
m_containerEntity->SetName(sourcePath.Filename().Native());
|
||||
}
|
||||
|
||||
void Instance::SetContainerEntityName(AZStd::string_view containerName)
|
||||
{
|
||||
m_containerEntity->SetName(containerName);
|
||||
}
|
||||
|
||||
bool Instance::AddEntity(AZ::Entity& entity)
|
||||
@@ -154,7 +158,7 @@ namespace AzToolsFramework
|
||||
if (instanceToTemplateEntityIdIterator != m_instanceToTemplateEntityIdMap.end())
|
||||
{
|
||||
entityAliasToRemove = instanceToTemplateEntityIdIterator->second;
|
||||
bool isEntityRemoved = m_instanceEntityMapper->UnregisterEntity(entityId) &&
|
||||
[[maybe_unused]] bool isEntityRemoved = m_instanceEntityMapper->UnregisterEntity(entityId) &&
|
||||
m_templateToInstanceEntityIdMap.erase(entityAliasToRemove) && m_instanceToTemplateEntityIdMap.erase(entityId);
|
||||
AZ_Assert(isEntityRemoved,
|
||||
"Prefab - Failed to remove entity with id %s with a Prefab Instance derived from source asset %s "
|
||||
@@ -317,7 +321,6 @@ namespace AzToolsFramework
|
||||
removedNestedInstance = AZStd::move(nestedInstanceIterator->second);
|
||||
|
||||
removedNestedInstance->m_parent = nullptr;
|
||||
removedNestedInstance->m_alias = InstanceAlias();
|
||||
|
||||
m_nestedInstances.erase(instanceAlias);
|
||||
}
|
||||
@@ -392,6 +395,14 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
void Instance::GetNestedInstances(const AZStd::function<void(AZStd::unique_ptr<Instance>&)>& callback)
|
||||
{
|
||||
for (auto& [instanceAlias, instance] : m_nestedInstances)
|
||||
{
|
||||
callback(instance);
|
||||
}
|
||||
}
|
||||
|
||||
void Instance::GetEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback)
|
||||
{
|
||||
for (auto& [entityAlias, entity] : m_entities)
|
||||
@@ -563,7 +574,7 @@ namespace AzToolsFramework
|
||||
|
||||
AZ::EntityId Instance::GetContainerEntityId() const
|
||||
{
|
||||
return m_containerEntity->GetId();
|
||||
return m_containerEntity ? m_containerEntity->GetId() : AZ::EntityId();
|
||||
}
|
||||
|
||||
bool Instance::HasContainerEntity() const
|
||||
|
||||
@@ -80,6 +80,7 @@ namespace AzToolsFramework
|
||||
|
||||
const AZ::IO::Path& GetTemplateSourcePath() const;
|
||||
void SetTemplateSourcePath(AZ::IO::PathView sourcePath);
|
||||
void SetContainerEntityName(AZStd::string_view containerName);
|
||||
|
||||
bool AddEntity(AZ::Entity& entity);
|
||||
bool AddEntity(AZ::Entity& entity, EntityAlias entityAlias);
|
||||
@@ -113,6 +114,7 @@ namespace AzToolsFramework
|
||||
void GetConstEntities(const AZStd::function<bool(const AZ::Entity&)>& callback);
|
||||
void GetNestedEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback);
|
||||
void GetEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback);
|
||||
void GetNestedInstances(const AZStd::function<void(AZStd::unique_ptr<Instance>&)>& callback);
|
||||
|
||||
/**
|
||||
* Gets the alias for a given EnitityId in the Instance DOM.
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ namespace AzToolsFramework
|
||||
class InstanceEntityScrubber
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(InstanceEntityScrubber, "{0BC12562-C240-48AD-89C6-EDF572C9B485}");
|
||||
AZ_TYPE_INFO(InstanceEntityScrubber, "{0BC12562-C240-48AD-89C6-EDF572C9B485}");
|
||||
|
||||
explicit InstanceEntityScrubber(Instance::EntityList& entities);
|
||||
|
||||
|
||||
+4
-5
@@ -209,7 +209,7 @@ namespace AzToolsFramework
|
||||
EntityList entitiesInInstance;
|
||||
entitiesInInstance.reserve(instance->m_entities.size() + 1);
|
||||
|
||||
if (instance->m_containerEntity->GetId().IsValid())
|
||||
if (instance->m_containerEntity && instance->m_containerEntity->GetId().IsValid())
|
||||
{
|
||||
entitiesInInstance.emplace_back(instance->m_containerEntity.get());
|
||||
}
|
||||
@@ -219,11 +219,10 @@ namespace AzToolsFramework
|
||||
entitiesInInstance.emplace_back(entity.get());
|
||||
}
|
||||
|
||||
InstanceEntityScrubber** instanceEntityScrubber = jsonDeserializerContext.GetMetadata().Find<InstanceEntityScrubber*>();
|
||||
if (instanceEntityScrubber && (*instanceEntityScrubber))
|
||||
|
||||
InstanceEntityScrubber* instanceEntityScrubber = jsonDeserializerContext.GetMetadata().Find<InstanceEntityScrubber>();
|
||||
if (instanceEntityScrubber)
|
||||
{
|
||||
(*instanceEntityScrubber)->AddEntitiesToScrub(entitiesInInstance);
|
||||
instanceEntityScrubber->AddEntitiesToScrub(entitiesInInstance);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -43,14 +43,12 @@ namespace AzToolsFramework
|
||||
const PrefabDom& modifiedState, const LinkId linkId) = 0;
|
||||
|
||||
//! Updates the affected template for a given entityId using the providedPatch
|
||||
virtual bool PatchEntityInTemplate(PrefabDomValue& providedPatch, const AZ::EntityId& entityId) = 0;
|
||||
|
||||
virtual bool PatchEntityInTemplate(PrefabDomValue& providedPatch, const EntityAlias& entityAlias, const TemplateId& templateId) = 0;
|
||||
virtual bool PatchEntityInTemplate(PrefabDom& providedPatch, AZ::EntityId entityId) = 0;
|
||||
|
||||
virtual void AppendEntityAliasToPatchPaths(PrefabDom& providedPatch, const AZ::EntityId& entityId) = 0;
|
||||
|
||||
//! Updates the template links (updating instances) for the given templateId using the providedPatch
|
||||
virtual void PatchTemplate(PrefabDomValue& providedPatch, const TemplateId& templateId) = 0;
|
||||
virtual bool PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId) = 0;
|
||||
|
||||
virtual void ApplyPatchesToInstance(const AZ::EntityId& entityId, PrefabDom& patches, const Instance& instanceToAddPatches) = 0;
|
||||
|
||||
|
||||
+14
-54
@@ -107,7 +107,7 @@ namespace AzToolsFramework
|
||||
return result.GetProcessing() != AZ::JsonSerializationResult::Processing::Halted;
|
||||
}
|
||||
|
||||
bool InstanceToTemplatePropagator::PatchEntityInTemplate(PrefabDomValue& providedPatch, const AZ::EntityId& entityId)
|
||||
bool InstanceToTemplatePropagator::PatchEntityInTemplate(PrefabDom& providedPatch, AZ::EntityId entityId)
|
||||
{
|
||||
InstanceOptionalReference instanceOptionalReference = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
|
||||
@@ -119,54 +119,10 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
//get template space associated with instance
|
||||
Instance& instance = instanceOptionalReference->get();
|
||||
TemplateId templateId = instance.GetTemplateId();
|
||||
|
||||
//alias entity goes by in template -> get via owning instance map
|
||||
AZStd::optional<EntityAlias> entityAlias = instance.GetEntityAlias(entityId);
|
||||
|
||||
if (!entityAlias)
|
||||
{
|
||||
AZ_Error("Prefab", false, "Failed to find an entity alias for the provided entity");
|
||||
return false;
|
||||
}
|
||||
|
||||
PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId);
|
||||
|
||||
return PatchEntityInTemplate(providedPatch, entityAlias.value(), templateId);
|
||||
}
|
||||
|
||||
bool InstanceToTemplatePropagator::PatchEntityInTemplate(PrefabDomValue& providedPatch, const EntityAlias& entityAlias, const TemplateId& templateId)
|
||||
{
|
||||
PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId);
|
||||
|
||||
//query into the template dom for the alias
|
||||
PrefabDomValueReference entityList = PrefabDomUtils::FindPrefabDomValue(templateDomReference, PrefabDomUtils::EntitiesName);
|
||||
|
||||
if (!entityList)
|
||||
{
|
||||
AZ_Error("Prefab", false, "Cannot patch entity in Template with id [%llu] because entity couldn't be found in the template", templateId);
|
||||
return false;
|
||||
}
|
||||
|
||||
PrefabDomValueReference entity = PrefabDomUtils::FindPrefabDomValue(entityList->get(), entityAlias.c_str());
|
||||
|
||||
if (!entity)
|
||||
{
|
||||
AZ_Error("Prefab", false, "Failed to aquire entity value reference");
|
||||
return false;
|
||||
}
|
||||
|
||||
//apply patch to section
|
||||
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(entity->get(),
|
||||
templateDomReference.GetAllocator(), providedPatch, AZ::JsonMergeApproach::JsonPatch);
|
||||
|
||||
AZ_Error("Prefab", result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success, "Patch was not successfully applied")
|
||||
|
||||
//trigger propagation
|
||||
m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId);
|
||||
return true;
|
||||
//get template id associated with instance
|
||||
TemplateId templateId = instanceOptionalReference->get().GetTemplateId();
|
||||
AppendEntityAliasToPatchPaths(providedPatch, entityId);
|
||||
return PatchTemplate(providedPatch, templateId);
|
||||
}
|
||||
|
||||
void InstanceToTemplatePropagator::AppendEntityAliasToPatchPaths(PrefabDom& providedPatch, const AZ::EntityId& entityId)
|
||||
@@ -216,7 +172,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceToTemplatePropagator::PatchTemplate(PrefabDomValue& providedPatch, const TemplateId& templateId)
|
||||
bool InstanceToTemplatePropagator::PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId)
|
||||
{
|
||||
PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId);
|
||||
|
||||
@@ -224,14 +180,17 @@ namespace AzToolsFramework
|
||||
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(templateDomReference,
|
||||
templateDomReference.GetAllocator(), providedPatch, AZ::JsonMergeApproach::JsonPatch);
|
||||
|
||||
AZ_Error("Prefab", result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success,
|
||||
"Patch was not successfully applied");
|
||||
|
||||
//trigger propagation
|
||||
if (result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success)
|
||||
{
|
||||
m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, true);
|
||||
m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("Prefab", false, "Patch was not successfully applied");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,6 +247,8 @@ namespace AzToolsFramework
|
||||
|
||||
AddPatchesToLink(patches, linkToApplyPatches);
|
||||
linkToApplyPatches.UpdateTarget();
|
||||
|
||||
m_prefabSystemComponentInterface->SetTemplateDirtyFlag(linkToApplyPatches.GetTargetTemplateId(), true);
|
||||
m_prefabSystemComponentInterface->PropagateTemplateChanges(linkToApplyPatches.GetTargetTemplateId());
|
||||
}
|
||||
|
||||
@@ -314,7 +275,6 @@ namespace AzToolsFramework
|
||||
PrefabDom& linkDom = link.GetLinkDom();
|
||||
PrefabDomValueReference linkPatchesReference =
|
||||
PrefabDomUtils::FindPrefabDomValue(linkDom, PrefabDomUtils::PatchesName);
|
||||
PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(link.GetTargetTemplateId());
|
||||
|
||||
// This logic only covers addition of patches. If patches already exists, the given list of patches must be appended to them.
|
||||
if (!linkPatchesReference.has_value())
|
||||
|
||||
+2
-4
@@ -31,21 +31,19 @@ namespace AzToolsFramework
|
||||
bool GeneratePatch(PrefabDom& generatedPatch, const PrefabDom& initialState, const PrefabDom& modifiedState) override;
|
||||
bool GeneratePatchForLink(PrefabDom& generatedPatch, const PrefabDom& initialState,
|
||||
const PrefabDom& modifiedState, LinkId linkId) override;
|
||||
bool PatchEntityInTemplate(PrefabDomValue& providedPatch, const AZ::EntityId& entityId) override;
|
||||
bool PatchEntityInTemplate(PrefabDomValue& providedPatch, const EntityAlias& entityAlias, const TemplateId& templateId) override;
|
||||
bool PatchEntityInTemplate(PrefabDom& providedPatch, AZ::EntityId entityId) override;
|
||||
|
||||
void AppendEntityAliasToPatchPaths(PrefabDom& providedPatch, const AZ::EntityId& entityId) override;
|
||||
|
||||
InstanceOptionalReference GetTopMostInstanceInHierarchy(AZ::EntityId entityId);
|
||||
|
||||
void PatchTemplate(PrefabDomValue& providedPatch, const AzToolsFramework::Prefab::TemplateId& templateId) override;
|
||||
bool PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId) override;
|
||||
|
||||
void ApplyPatchesToInstance(const AZ::EntityId& entityId, PrefabDom& patches, const Instance& instanceToAddPatches) override;
|
||||
|
||||
void AddPatchesToLink(PrefabDom& patches, Link& link);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
InstanceEntityMapperInterface* m_instanceEntityMapperInterface;
|
||||
PrefabSystemComponentInterface* m_prefabSystemComponentInterface;
|
||||
|
||||
+41
-9
@@ -15,10 +15,12 @@
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/TemplateInstanceMapperInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
|
||||
#include <AzToolsFramework/Prefab/Template/Template.h>
|
||||
#include <AzToolsFramework/UI/Outliner/EntityOutlinerWidgetInterface.h>
|
||||
@@ -115,14 +117,32 @@ namespace AzToolsFramework
|
||||
"Could not find Template using Id '%llu'. Unable to update Instance.",
|
||||
currentTemplateId);
|
||||
|
||||
// Remove the instance from update queue if its corresponding template couldn't be found
|
||||
isUpdateSuccessful = false;
|
||||
m_instancesUpdateQueue.pop();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
auto findInstancesResult = m_templateInstanceMapperInterface->FindInstancesOwnedByTemplate(instanceTemplateId)->get();
|
||||
|
||||
if (findInstancesResult.find(instanceToUpdate) == findInstancesResult.end())
|
||||
{
|
||||
// Since nested instances get reconstructed during propagation, remove any nested instance that no longer
|
||||
// maps to a template.
|
||||
isUpdateSuccessful = false;
|
||||
m_instancesUpdateQueue.pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
Template& currentTemplate = currentTemplateReference->get();
|
||||
Instance::EntityList newEntities;
|
||||
if (!PrefabDomUtils::LoadInstanceFromPrefabDom(
|
||||
*instanceToUpdate, newEntities, currentTemplate.GetPrefabDom()))
|
||||
if (PrefabDomUtils::LoadInstanceFromPrefabDom(*instanceToUpdate, newEntities, currentTemplate.GetPrefabDom()))
|
||||
{
|
||||
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
|
||||
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, newEntities);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error(
|
||||
"Prefab", false,
|
||||
@@ -132,22 +152,34 @@ namespace AzToolsFramework
|
||||
|
||||
isUpdateSuccessful = false;
|
||||
}
|
||||
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
|
||||
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, newEntities);
|
||||
|
||||
m_instancesUpdateQueue.pop();
|
||||
|
||||
}
|
||||
|
||||
for (auto entityIdIterator = selectedEntityIds.begin(); entityIdIterator != selectedEntityIds.end(); entityIdIterator++)
|
||||
{
|
||||
// Since entities get recreated during propagation, we need to check whether the entities correspoding to the list
|
||||
// of selected entity ids are present or not.
|
||||
AZ::Entity* entity = GetEntityById(*entityIdIterator);
|
||||
if (entity == nullptr)
|
||||
{
|
||||
selectedEntityIds.erase(entityIdIterator--);
|
||||
}
|
||||
}
|
||||
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, selectedEntityIds);
|
||||
|
||||
// Enable the Outliner
|
||||
AZ::SystemTickBus::QueueFunction([entityOutlinerWidgetInterface]() {
|
||||
if (entityOutlinerWidgetInterface)
|
||||
if (entityOutlinerWidgetInterface)
|
||||
{
|
||||
entityOutlinerWidgetInterface->SetUpdatesEnabled(true);
|
||||
|
||||
auto prefabPublicInterface = AZ::Interface<PrefabPublicInterface>::Get();
|
||||
if (prefabPublicInterface)
|
||||
{
|
||||
entityOutlinerWidgetInterface->SetUpdatesEnabled(true);
|
||||
AZ::EntityId rootEntityId = prefabPublicInterface->GetLevelInstanceContainerEntityId();
|
||||
entityOutlinerWidgetInterface->ExpandEntityChildren(rootEntityId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
m_updatingTemplateInstancesInQueue = false;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/JSON/prettywriter.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
@@ -78,6 +79,11 @@ namespace AzToolsFramework
|
||||
|
||||
bool LoadInstanceFromPrefabDom(Instance& instance, const PrefabDom& prefabDom, LoadInstanceFlags flags)
|
||||
{
|
||||
// When entities are rebuilt they are first destroyed. As a result any assets they were exclusively holding on to will
|
||||
// be released and reloaded once the entities are built up again. By suspending asset release temporarily the asset reload
|
||||
// is avoided.
|
||||
AZ::Data::AssetManager::Instance().SuspendAssetRelease();
|
||||
|
||||
InstanceEntityIdMapper entityIdMapper;
|
||||
entityIdMapper.SetLoadingInstance(instance);
|
||||
if ((flags & LoadInstanceFlags::AssignRandomEntityId) == LoadInstanceFlags::AssignRandomEntityId)
|
||||
@@ -91,10 +97,12 @@ namespace AzToolsFramework
|
||||
// data has strict typing and doesn't look for inheritance both have to be explicitly added so they're found both locations.
|
||||
settings.m_metadata.Add(static_cast<AZ::JsonEntityIdSerializer::JsonEntityIdMapper*>(&entityIdMapper));
|
||||
settings.m_metadata.Add(&entityIdMapper);
|
||||
|
||||
|
||||
AZ::JsonSerializationResult::ResultCode result =
|
||||
AZ::JsonSerialization::Load(instance, prefabDom, settings);
|
||||
|
||||
AZ::Data::AssetManager::Instance().ResumeAssetRelease();
|
||||
|
||||
if (result.GetProcessing() == AZ::JsonSerializationResult::Processing::Halted)
|
||||
{
|
||||
AZ_Error("Prefab", false,
|
||||
@@ -110,6 +118,11 @@ namespace AzToolsFramework
|
||||
bool LoadInstanceFromPrefabDom(
|
||||
Instance& instance, Instance::EntityList& newlyAddedEntities, const PrefabDom& prefabDom, LoadInstanceFlags flags)
|
||||
{
|
||||
// When entities are rebuilt they are first destroyed. As a result any assets they were exclusively holding on to will
|
||||
// be released and reloaded once the entities are built up again. By suspending asset release temporarily the asset reload
|
||||
// is avoided.
|
||||
AZ::Data::AssetManager::Instance().SuspendAssetRelease();
|
||||
|
||||
InstanceEntityIdMapper entityIdMapper;
|
||||
entityIdMapper.SetLoadingInstance(instance);
|
||||
if ((flags & LoadInstanceFlags::AssignRandomEntityId) == LoadInstanceFlags::AssignRandomEntityId)
|
||||
@@ -123,16 +136,16 @@ namespace AzToolsFramework
|
||||
// data has strict typing and doesn't look for inheritance both have to be explicitly added so they're found both locations.
|
||||
settings.m_metadata.Add(static_cast<AZ::JsonEntityIdSerializer::JsonEntityIdMapper*>(&entityIdMapper));
|
||||
settings.m_metadata.Add(&entityIdMapper);
|
||||
settings.m_metadata.Create<InstanceEntityScrubber>(newlyAddedEntities);
|
||||
|
||||
InstanceEntityScrubber instanceEntityScrubber(newlyAddedEntities);
|
||||
settings.m_metadata.Add(&instanceEntityScrubber);
|
||||
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::Load(instance, prefabDom, settings);
|
||||
|
||||
AZ::JsonSerializationResult::ResultCode result =
|
||||
AZ::JsonSerialization::Load(instance, prefabDom, settings);
|
||||
AZ::Data::AssetManager::Instance().ResumeAssetRelease();
|
||||
|
||||
if (result.GetProcessing() == AZ::JsonSerializationResult::Processing::Halted)
|
||||
{
|
||||
AZ_Error("Prefab", false,
|
||||
AZ_Error(
|
||||
"Prefab", false,
|
||||
"Failed to de-serialize Prefab Instance from Prefab DOM. "
|
||||
"Unable to proceed.");
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace AzToolsFramework
|
||||
auto settingsRegistry = AZ::SettingsRegistry::Get();
|
||||
AZ_Assert(settingsRegistry, "Settings registry is not set");
|
||||
|
||||
bool result =
|
||||
[[maybe_unused]] bool result =
|
||||
settingsRegistry->Get(m_projectPathWithOsSeparator.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectPath);
|
||||
AZ_Assert(result, "Couldn't retrieve project root path");
|
||||
m_projectPathWithSlashSeparator = AZ::IO::Path(m_projectPathWithOsSeparator.Native(), '/').MakePreferred();
|
||||
@@ -182,7 +182,6 @@ namespace AzToolsFramework
|
||||
for (PrefabDomValue::MemberIterator instanceIterator = instances.MemberBegin(); instanceIterator != instances.MemberEnd();
|
||||
++instanceIterator)
|
||||
{
|
||||
const PrefabDomValue& instance = instanceIterator->value;
|
||||
if (!LoadNestedInstance(instanceIterator, newTemplateId, progressedFilePathsSet))
|
||||
{
|
||||
isLoadedWithErrors = true;
|
||||
@@ -349,8 +348,7 @@ namespace AzToolsFramework
|
||||
"Prefab", false,
|
||||
"PrefabLoader::SaveTemplate - Unable to save Prefab Template with id: %llu. "
|
||||
"Template with that id is invalid",
|
||||
templateId
|
||||
);
|
||||
templateId);
|
||||
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
@@ -15,18 +15,20 @@
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Utils/TypeHash.h>
|
||||
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
|
||||
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
|
||||
#include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/InstanceEntityIdMapper.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/InstanceToTemplateInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabLoaderInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabUndo.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabUndoHelpers.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
@@ -36,12 +38,14 @@ namespace AzToolsFramework
|
||||
void PrefabPublicHandler::RegisterPrefabPublicHandlerInterface()
|
||||
{
|
||||
m_instanceEntityMapperInterface = AZ::Interface<InstanceEntityMapperInterface>::Get();
|
||||
AZ_Assert(
|
||||
m_instanceEntityMapperInterface, "PrefabPublicHandler - Could not retrieve instance of InstanceEntityMapperInterface");
|
||||
AZ_Assert(m_instanceEntityMapperInterface, "PrefabPublicHandler - Could not retrieve instance of InstanceEntityMapperInterface");
|
||||
|
||||
m_instanceToTemplateInterface = AZ::Interface<InstanceToTemplateInterface>::Get();
|
||||
AZ_Assert(m_instanceToTemplateInterface, "PrefabPublicHandler - Could not retrieve instance of InstanceToTemplateInterface");
|
||||
|
||||
m_prefabLoaderInterface = AZ::Interface<PrefabLoaderInterface>::Get();
|
||||
AZ_Assert(m_prefabLoaderInterface, "Could not get PrefabLoaderInterface on PrefabPublicHandler construction.");
|
||||
|
||||
m_prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
|
||||
AZ_Assert(m_prefabSystemComponentInterface, "Could not get PrefabSystemComponentInterface on PrefabPublicHandler construction.");
|
||||
|
||||
@@ -57,115 +61,235 @@ namespace AzToolsFramework
|
||||
m_prefabUndoCache.Destroy();
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZStd::string_view filePath)
|
||||
PrefabOperationResult PrefabPublicHandler::CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath)
|
||||
{
|
||||
EntityList inputEntityList, topLevelEntities;
|
||||
AZ::EntityId commonRootEntityId;
|
||||
InstanceOptionalReference commonRootEntityOwningInstance;
|
||||
PrefabOperationResult findCommonRootOutcome = FindCommonRootOwningInstance(
|
||||
entityIds, inputEntityList, topLevelEntities, commonRootEntityId, commonRootEntityOwningInstance);
|
||||
if (!findCommonRootOutcome.IsSuccess())
|
||||
{
|
||||
return findCommonRootOutcome;
|
||||
}
|
||||
|
||||
InstanceOptionalReference instanceToCreate;
|
||||
{
|
||||
// Initialize Undo Batch object
|
||||
ScopedUndoBatch undoBatch("Create Prefab");
|
||||
|
||||
PrefabDom commonRootInstanceDomBeforeCreate;
|
||||
m_instanceToTemplateInterface->GenerateDomForInstance(
|
||||
commonRootInstanceDomBeforeCreate, commonRootEntityOwningInstance->get());
|
||||
|
||||
AZStd::vector<AZ::Entity*> entities;
|
||||
AZStd::vector<AZStd::unique_ptr<Instance>> instances;
|
||||
|
||||
// Retrieve all entities affected and identify Instances
|
||||
if (!RetrieveAndSortPrefabEntitiesAndInstances(inputEntityList, commonRootEntityOwningInstance->get(), entities, instances))
|
||||
{
|
||||
return AZ::Failure(
|
||||
AZStd::string("Could not create a new prefab out of the entities provided - entities do not share a common root."));
|
||||
}
|
||||
|
||||
// When we create a prefab with other prefab instances, we have to remove the existing links between the source and
|
||||
// target templates of the other instances.
|
||||
for (auto& nestedInstance : instances)
|
||||
{
|
||||
PrefabUndoHelpers::RemoveLink(
|
||||
nestedInstance->GetTemplateId(), commonRootEntityOwningInstance->get().GetTemplateId(),
|
||||
nestedInstance->GetInstanceAlias(), nestedInstance->GetLinkId(), undoBatch.GetUndoBatch());
|
||||
}
|
||||
|
||||
PrefabUndoHelpers::UpdatePrefabInstance(
|
||||
commonRootEntityOwningInstance->get(), "Update prefab instance", commonRootInstanceDomBeforeCreate,
|
||||
undoBatch.GetUndoBatch());
|
||||
|
||||
auto prefabEditorEntityOwnershipInterface = AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
if (!prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error "
|
||||
"(PrefabEditorEntityOwnershipInterface unavailable)."));
|
||||
}
|
||||
|
||||
// Create the Prefab
|
||||
instanceToCreate = prefabEditorEntityOwnershipInterface->CreatePrefab(
|
||||
entities, AZStd::move(instances), filePath, commonRootEntityOwningInstance);
|
||||
|
||||
if (!instanceToCreate)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error "
|
||||
"(A null instance is returned)."));
|
||||
}
|
||||
|
||||
AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId();
|
||||
|
||||
instanceToCreate->get().GetNestedInstances([&](AZStd::unique_ptr<Instance>& nestedInstance) {
|
||||
AZ_Assert(nestedInstance, "Invalid nested instance found in the new prefab created.");
|
||||
EntityOptionalReference nestedInstanceContainerEntity = nestedInstance->GetContainerEntity();
|
||||
AZ_Assert(
|
||||
nestedInstanceContainerEntity, "Invalid container entity found for the nested instance used in prefab creation.");
|
||||
CreateLink(
|
||||
{&nestedInstanceContainerEntity->get()}, *nestedInstance, instanceToCreate->get().GetTemplateId(),
|
||||
undoBatch.GetUndoBatch(), containerEntityId);
|
||||
});
|
||||
|
||||
CreateLink(
|
||||
topLevelEntities, instanceToCreate->get(), commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch(),
|
||||
commonRootEntityId);
|
||||
|
||||
// Change top level entities to be parented to the container entity
|
||||
// Mark them as dirty so this change is correctly applied to the template
|
||||
for (AZ::Entity* topLevelEntity : topLevelEntities)
|
||||
{
|
||||
m_prefabUndoCache.UpdateCache(topLevelEntity->GetId());
|
||||
undoBatch.MarkEntityDirty(topLevelEntity->GetId());
|
||||
AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId);
|
||||
}
|
||||
|
||||
// Select Container Entity
|
||||
{
|
||||
auto selectionUndo = aznew SelectionCommand({containerEntityId}, "Select Prefab Container Entity");
|
||||
selectionUndo->SetParent(undoBatch.GetUndoBatch());
|
||||
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::RunRedoSeparately, selectionUndo);
|
||||
}
|
||||
}
|
||||
|
||||
// Save Template to file
|
||||
m_prefabLoaderInterface->SaveTemplate(instanceToCreate->get().GetTemplateId());
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::InstantiatePrefab(
|
||||
AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position)
|
||||
{
|
||||
auto prefabEditorEntityOwnershipInterface = AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
if (!prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not instantiate prefab - internal error "
|
||||
"(PrefabEditorEntityOwnershipInterface unavailable)."));
|
||||
}
|
||||
|
||||
InstanceOptionalReference instanceToParentUnder;
|
||||
|
||||
// Get parent entity and owning instance
|
||||
if (parent.IsValid())
|
||||
{
|
||||
instanceToParentUnder = m_instanceEntityMapperInterface->FindOwningInstance(parent);
|
||||
}
|
||||
|
||||
if (!instanceToParentUnder.has_value())
|
||||
{
|
||||
instanceToParentUnder = prefabEditorEntityOwnershipInterface->GetRootPrefabInstance();
|
||||
parent = instanceToParentUnder->get().GetContainerEntityId();
|
||||
}
|
||||
|
||||
{
|
||||
// Initialize Undo Batch object
|
||||
ScopedUndoBatch undoBatch("Instantiate Prefab");
|
||||
|
||||
PrefabDom instanceToParentUnderDomBeforeCreate;
|
||||
m_instanceToTemplateInterface->GenerateDomForInstance(
|
||||
instanceToParentUnderDomBeforeCreate, instanceToParentUnder->get());
|
||||
|
||||
// Instantiate the Prefab
|
||||
auto instanceToCreate = prefabEditorEntityOwnershipInterface->InstantiatePrefab(filePath, instanceToParentUnder);
|
||||
|
||||
if (!instanceToCreate)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not instantiate the prefab provided - internal error "
|
||||
"(A null instance is returned)."));
|
||||
}
|
||||
|
||||
PrefabUndoHelpers::UpdatePrefabInstance(
|
||||
instanceToParentUnder->get(), "Update prefab instance", instanceToParentUnderDomBeforeCreate, undoBatch.GetUndoBatch());
|
||||
|
||||
CreateLink({}, instanceToCreate->get(), instanceToParentUnder->get().GetTemplateId(),
|
||||
undoBatch.GetUndoBatch(), parent);
|
||||
AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId();
|
||||
|
||||
// Apply position
|
||||
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetWorldTranslation, position);
|
||||
}
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::FindCommonRootOwningInstance(
|
||||
const AZStd::vector<AZ::EntityId>& entityIds, EntityList& inputEntityList, EntityList& topLevelEntities,
|
||||
AZ::EntityId& commonRootEntityId, InstanceOptionalReference& commonRootEntityOwningInstance)
|
||||
{
|
||||
// Retrieve entityList from entityIds
|
||||
EntityList inputEntityList;
|
||||
EntityIdListToEntityList(entityIds, inputEntityList);
|
||||
inputEntityList = EntityIdListToEntityList(entityIds);
|
||||
|
||||
// Find common root and top level entities
|
||||
bool entitiesHaveCommonRoot = false;
|
||||
AZ::EntityId commonRootEntityId;
|
||||
EntityList topLevelEntities;
|
||||
|
||||
AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult(
|
||||
entitiesHaveCommonRoot,
|
||||
&AzToolsFramework::ToolsApplicationRequests::FindCommonRootInactive,
|
||||
inputEntityList,
|
||||
commonRootEntityId,
|
||||
&topLevelEntities
|
||||
);
|
||||
entitiesHaveCommonRoot, &AzToolsFramework::ToolsApplicationRequests::FindCommonRootInactive, inputEntityList,
|
||||
commonRootEntityId, &topLevelEntities);
|
||||
|
||||
// Bail if entities don't share a common root
|
||||
if (!entitiesHaveCommonRoot)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - entities do not share a common root."));
|
||||
}
|
||||
|
||||
AZ::Entity* commonRootEntity = nullptr;
|
||||
if (commonRootEntityId.IsValid())
|
||||
{
|
||||
commonRootEntity = GetEntityById(commonRootEntityId);
|
||||
return AZ::Failure(AZStd::string("Failed to create a prefab: Provided entities do not share a common root."));
|
||||
}
|
||||
|
||||
// Retrieve the owning instance of the common root entity, which will be our new instance's parent instance.
|
||||
InstanceOptionalReference commonRootEntityOwningInstance = GetOwnerInstanceByEntityId(commonRootEntityId);
|
||||
AZ_Assert(commonRootEntityOwningInstance.has_value(), "Failed to create prefab : "
|
||||
"Couldn't get a valid owning instance for the common root entity of the enities provided");
|
||||
|
||||
AZStd::vector<AZ::Entity*> entities;
|
||||
AZStd::vector<AZStd::unique_ptr<Instance>> instances;
|
||||
|
||||
// Retrieve all entities affected and identify Instances
|
||||
if (!RetrieveAndSortPrefabEntitiesAndInstances(inputEntityList, commonRootEntityOwningInstance->get(), entities, instances))
|
||||
commonRootEntityOwningInstance = GetOwnerInstanceByEntityId(commonRootEntityId);
|
||||
if (!commonRootEntityOwningInstance)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - entities do not share a common root."));
|
||||
AZ_Assert(
|
||||
false,
|
||||
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided");
|
||||
return AZ::Failure(AZStd::string(
|
||||
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided"));
|
||||
}
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
auto prefabEditorEntityOwnershipInterface = AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
if (!prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error "
|
||||
"(PrefabEditorEntityOwnershipInterface unavailable)."));
|
||||
}
|
||||
void PrefabPublicHandler::CreateLink(
|
||||
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
|
||||
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId)
|
||||
{
|
||||
AZ::EntityId containerEntityId = sourceInstance.GetContainerEntityId();
|
||||
AZ::Entity* containerEntity = GetEntityById(containerEntityId);
|
||||
Prefab::PrefabDom containerEntityDomBefore;
|
||||
m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomBefore, *containerEntity);
|
||||
|
||||
InstanceOptionalReference instance = prefabEditorEntityOwnershipInterface->CreatePrefab(
|
||||
entities, AZStd::move(instances), filePath, commonRootEntityOwningInstance);
|
||||
|
||||
if (!instance)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error "
|
||||
"(A null instance is returned)."));
|
||||
}
|
||||
|
||||
AZ::EntityId containerEntityId = instance->get().GetContainerEntityId();
|
||||
AZ::Vector3 containerEntityTranslation(AZ::Vector3::CreateZero());
|
||||
AZ::Quaternion containerEntityRotation(AZ::Quaternion::CreateZero());
|
||||
|
||||
// Set the transform (translation, rotation) of the container entity
|
||||
GenerateContainerEntityTransform(topLevelEntities, containerEntityTranslation, containerEntityRotation);
|
||||
|
||||
// Set container entity to be child of common root
|
||||
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetParent, commonRootEntityId);
|
||||
|
||||
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetLocalTranslation, containerEntityTranslation);
|
||||
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetLocalRotationQuaternion, containerEntityRotation);
|
||||
|
||||
// Set container entity to be child of common root
|
||||
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetParent, commonRootEntityId);
|
||||
|
||||
// Assign the EditorPrefabComponent to the instance container
|
||||
EntityCompositionRequests::AddComponentsOutcome outcome;
|
||||
EntityCompositionRequestBus::BroadcastResult(
|
||||
outcome, &EntityCompositionRequests::AddComponentsToEntities, EntityIdList{containerEntityId},
|
||||
AZ::ComponentTypeList{azrtti_typeid<AzToolsFramework::Prefab::EditorPrefabComponent>()});
|
||||
|
||||
// Change top level entities to be parented to the container entity
|
||||
for (AZ::Entity* topLevelEntity : topLevelEntities)
|
||||
{
|
||||
AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId);
|
||||
}
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
PrefabDom containerEntityDomAfter;
|
||||
m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomAfter, *containerEntity);
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::InstantiatePrefab(AZStd::string_view /*filePath*/, AZ::EntityId /*parent*/, AZ::Vector3 /*position*/)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Prefab - InstantiatePrefab is yet to be implemented."));
|
||||
PrefabDom patch;
|
||||
m_instanceToTemplateInterface->GeneratePatch(patch, containerEntityDomBefore, containerEntityDomAfter);
|
||||
m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(patch, containerEntityId);
|
||||
|
||||
LinkId linkId = PrefabUndoHelpers::CreateLink(
|
||||
sourceInstance.GetTemplateId(), targetTemplateId, patch, sourceInstance.GetInstanceAlias(),
|
||||
undoBatch);
|
||||
|
||||
sourceInstance.SetLinkId(linkId);
|
||||
|
||||
// Update the cache - this prevents these changes from being stored in the regular undo/redo nodes
|
||||
m_prefabUndoCache.Store(containerEntityId, AZStd::move(containerEntityDomAfter));
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::SavePrefab(AZ::IO::Path filePath)
|
||||
{
|
||||
auto prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
|
||||
if (!prefabSystemComponentInterface)
|
||||
{
|
||||
AZ_Assert(
|
||||
false,
|
||||
"Prefab - PrefabPublicHandler - "
|
||||
"Prefab System Component Interface could not be found. "
|
||||
"Check that it is being correctly initialized.");
|
||||
return AZ::Failure(
|
||||
AZStd::string("SavePrefab - Internal error (Prefab System Component Interface could not be found)."));
|
||||
}
|
||||
|
||||
auto templateId = prefabSystemComponentInterface->GetTemplateIdFromFilePath(filePath.c_str());
|
||||
auto templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(filePath.c_str());
|
||||
|
||||
if (templateId == InvalidTemplateId)
|
||||
{
|
||||
@@ -173,14 +297,7 @@ namespace AzToolsFramework
|
||||
AZStd::string("SavePrefab - Path error. Path could be invalid, or the prefab may not be loaded in this level."));
|
||||
}
|
||||
|
||||
auto prefabLoaderInterface = AZ::Interface<PrefabLoaderInterface>::Get();
|
||||
if (prefabLoaderInterface == nullptr)
|
||||
{
|
||||
return AZ::Failure(AZStd::string(
|
||||
"Could not save prefab - internal error (PrefabLoaderInterface unavailable)."));
|
||||
}
|
||||
|
||||
if (!prefabLoaderInterface->SaveTemplate(templateId))
|
||||
if (!m_prefabLoaderInterface->SaveTemplate(templateId))
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not save prefab - internal error (Json write operation failure)."));
|
||||
}
|
||||
@@ -247,23 +364,8 @@ namespace AzToolsFramework
|
||||
|
||||
ToolsApplicationRequests::Bus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, selection);
|
||||
|
||||
PrefabDom instanceDomAfterUpdate;
|
||||
m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomAfterUpdate, entityOwningInstance);
|
||||
|
||||
// Generate the patch comparing the instance before and after the entity addition.
|
||||
PrefabDom patch;
|
||||
if (!m_instanceToTemplateInterface->GeneratePatch(patch, instanceDomBeforeUpdate, instanceDomAfterUpdate))
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format(
|
||||
"A valid patch couldn't be created for adding an entity with id '%llu'", static_cast<AZ::u64>(entityId)));
|
||||
}
|
||||
|
||||
// create undo node
|
||||
PrefabUndoInstance* state = aznew PrefabUndoInstance(AZStd::string::format("%llu", static_cast<AZ::u64>(entityId)));
|
||||
state->Capture(instanceDomBeforeUpdate, instanceDomAfterUpdate, entityOwningInstance.GetTemplateId());
|
||||
state->SetParent(undoBatch.GetUndoBatch());
|
||||
|
||||
state->Redo();
|
||||
PrefabUndoHelpers::UpdatePrefabInstance(
|
||||
entityOwningInstance, "Undo adding entity", instanceDomBeforeUpdate, undoBatch.GetUndoBatch());
|
||||
|
||||
return AZ::Success(entityId);
|
||||
}
|
||||
@@ -272,17 +374,17 @@ namespace AzToolsFramework
|
||||
AZ::EntityId entityId, UndoSystem::URSequencePoint* parentUndoBatch)
|
||||
{
|
||||
// Create Undo node on entities if they belong to an instance
|
||||
InstanceOptionalReference instanceOptionalReference = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
InstanceOptionalReference owningInstance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
|
||||
if (instanceOptionalReference.has_value())
|
||||
if (owningInstance.has_value())
|
||||
{
|
||||
PrefabDom beforeState;
|
||||
m_prefabUndoCache.Retrieve(entityId, beforeState);
|
||||
|
||||
PrefabDom afterState;
|
||||
AZ::Entity* entity = GetEntityById(entityId);
|
||||
if (entity)
|
||||
{
|
||||
PrefabDom beforeState;
|
||||
m_prefabUndoCache.Retrieve(entityId, beforeState);
|
||||
|
||||
m_instanceToTemplateInterface->GenerateDomForEntity(afterState, *entity);
|
||||
|
||||
PrefabDom patch;
|
||||
@@ -301,7 +403,10 @@ namespace AzToolsFramework
|
||||
// Update the cache
|
||||
m_prefabUndoCache.Store(entityId, AZStd::move(afterState));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
m_prefabUndoCache.PurgeCache(entityId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,26 +490,14 @@ namespace AzToolsFramework
|
||||
|
||||
PrefabRequestResult PrefabPublicHandler::HasUnsavedChanges(AZ::IO::Path prefabFilePath) const
|
||||
{
|
||||
auto prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
|
||||
if (!prefabSystemComponentInterface)
|
||||
{
|
||||
AZ_Assert(
|
||||
false,
|
||||
"Prefab - PrefabPublicHandler - "
|
||||
"Prefab System Component Interface could not be found. "
|
||||
"Check that it is being correctly initialized.");
|
||||
return AZ::Failure(
|
||||
AZStd::string("HasUnsavedChanges - Internal error (Prefab System Component Interface could not be found)."));
|
||||
}
|
||||
|
||||
auto templateId = prefabSystemComponentInterface->GetTemplateIdFromFilePath(prefabFilePath.c_str());
|
||||
auto templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(prefabFilePath.c_str());
|
||||
|
||||
if (templateId == InvalidTemplateId)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("HasUnsavedChanges - Path error. Path could be invalid, or the prefab may not be loaded in this level."));
|
||||
}
|
||||
|
||||
return AZ::Success(prefabSystemComponentInterface->IsTemplateDirty(templateId));
|
||||
return AZ::Success(m_prefabSystemComponentInterface->IsTemplateDirty(templateId));
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::DeleteEntitiesInInstance(const EntityIdList& entityIds)
|
||||
@@ -433,8 +526,7 @@ namespace AzToolsFramework
|
||||
InstanceOptionalReference instance = GetOwnerInstanceByEntityId(entityIds[0]);
|
||||
|
||||
// Retrieve entityList from entityIds
|
||||
EntityList inputEntityList;
|
||||
EntityIdListToEntityList(entityIds, inputEntityList);
|
||||
EntityList inputEntityList = EntityIdListToEntityList(entityIds);
|
||||
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
@@ -643,14 +735,17 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
bool PrefabPublicHandler::RetrieveAndSortPrefabEntitiesAndInstances(
|
||||
const EntityList& inputEntities, const Instance& commonRootEntityOwningInstance,
|
||||
const EntityList& inputEntities, Instance& commonRootEntityOwningInstance,
|
||||
EntityList& outEntities, AZStd::vector<AZStd::unique_ptr<Instance>>& outInstances) const
|
||||
{
|
||||
AZStd::queue<AZ::Entity*> entityQueue;
|
||||
|
||||
for (auto inputEntity : inputEntities)
|
||||
{
|
||||
entityQueue.push(inputEntity);
|
||||
if (inputEntity && !IsLevelInstanceContainerEntity(inputEntity->GetId()))
|
||||
{
|
||||
entityQueue.push(inputEntity);
|
||||
}
|
||||
}
|
||||
|
||||
// Support sets to easily identify if we're processing the same entity multiple times.
|
||||
@@ -664,17 +759,19 @@ namespace AzToolsFramework
|
||||
|
||||
// Get this entity's owning instance.
|
||||
InstanceOptionalReference owningInstance = m_instanceEntityMapperInterface->FindOwningInstance(entity->GetId());
|
||||
AZ_Assert(owningInstance.has_value(), "An error occored while retrieving entities and prefab instances : "
|
||||
"Owning instance of entity with id '%llu' couldn't be found", entity->GetId());
|
||||
AZ_Assert(
|
||||
owningInstance.has_value(),
|
||||
"An error occurred while retrieving entities and prefab instances : "
|
||||
"Owning instance of entity with id '%llu' couldn't be found",
|
||||
entity->GetId());
|
||||
|
||||
// Check if this entity is owned by the same instance owning the root.
|
||||
if (&owningInstance->get() == &commonRootEntityOwningInstance)
|
||||
{
|
||||
AZStd::unique_ptr<AZ::Entity> detachedEntity = owningInstance->get().DetachEntity(entity->GetId());
|
||||
// If it's the same instance, we can add this entity to the new instance entities.
|
||||
int priorEntitiesSize = entities.size();
|
||||
|
||||
entities.insert(detachedEntity.release());
|
||||
entities.insert(entity);
|
||||
|
||||
// If the size of entities increased, then it wasn't added before.
|
||||
// In that case, add the children of this entity to the queue.
|
||||
@@ -714,20 +811,18 @@ namespace AzToolsFramework
|
||||
|
||||
// Store results
|
||||
outEntities.clear();
|
||||
outEntities.resize(entities.size());
|
||||
AZStd::copy(entities.begin(), entities.end(), outEntities.begin());
|
||||
outEntities.reserve(entities.size());
|
||||
|
||||
for (AZ::Entity* entity : entities)
|
||||
{
|
||||
outEntities.emplace_back(commonRootEntityOwningInstance.DetachEntity(entity->GetId()).release());
|
||||
}
|
||||
|
||||
outInstances.clear();
|
||||
outInstances.reserve(instances.size());
|
||||
for (Instance* instancePtr : instances)
|
||||
{
|
||||
auto parentInstance = instancePtr->GetParentInstance();
|
||||
|
||||
if (parentInstance.has_value())
|
||||
{
|
||||
auto uniquePtr = parentInstance->get().DetachNestedInstance(instancePtr->GetInstanceAlias());
|
||||
outInstances.push_back(AZStd::move(uniquePtr));
|
||||
}
|
||||
outInstances.push_back(AZStd::move(commonRootEntityOwningInstance.DetachNestedInstance(instancePtr->GetInstanceAlias())));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -745,8 +840,20 @@ namespace AzToolsFramework
|
||||
for (AZ::EntityId entityId : entityIds)
|
||||
{
|
||||
InstanceOptionalReference owningInstance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
// If this is the container entity, it actually represents the instance so get its owner
|
||||
if (owningInstance->get().GetContainerEntityId() == entityId)
|
||||
|
||||
if (!owningInstance.has_value())
|
||||
{
|
||||
AZ_Assert(
|
||||
false,
|
||||
"An error occurred in function EntitiesBelongToSameInstance: "
|
||||
"Owning instance of entity with id '%llu' couldn't be found",
|
||||
entityId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this is a container entity, it actually represents a child instance so get its owner.
|
||||
// The only exception in the level root instance. We leave it as is to streamline operations.
|
||||
if (owningInstance->get().GetContainerEntityId() == entityId && !IsLevelInstanceContainerEntity(entityId))
|
||||
{
|
||||
owningInstance = owningInstance->get().GetParentInstance();
|
||||
}
|
||||
@@ -766,18 +873,5 @@ namespace AzToolsFramework
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PrefabPublicHandler::EntityIdListToEntityList(const EntityIdList& inputEntityIds, EntityList& outEntities)
|
||||
{
|
||||
outEntities.reserve(inputEntityIds.size());
|
||||
|
||||
for (AZ::EntityId entityId : inputEntityIds)
|
||||
{
|
||||
if (entityId.IsValid())
|
||||
{
|
||||
outEntities.emplace_back(GetEntityById(entityId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,10 @@ namespace AzToolsFramework
|
||||
namespace Prefab
|
||||
{
|
||||
class Instance;
|
||||
|
||||
class InstanceEntityMapperInterface;
|
||||
class InstanceToTemplateInterface;
|
||||
class PrefabLoaderInterface;
|
||||
class PrefabSystemComponentInterface;
|
||||
|
||||
class PrefabPublicHandler final
|
||||
@@ -42,8 +44,8 @@ namespace AzToolsFramework
|
||||
void UnregisterPrefabPublicHandlerInterface();
|
||||
|
||||
// PrefabPublicInterface...
|
||||
PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZStd::string_view filePath) override;
|
||||
PrefabOperationResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, AZ::Vector3 position) override;
|
||||
PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath) override;
|
||||
PrefabOperationResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) override;
|
||||
PrefabOperationResult SavePrefab(AZ::IO::Path filePath) override;
|
||||
PrefabEntityResult CreateEntity(AZ::EntityId parentId, const AZ::Vector3& position) override;
|
||||
|
||||
@@ -61,19 +63,46 @@ namespace AzToolsFramework
|
||||
|
||||
private:
|
||||
PrefabOperationResult DeleteFromInstance(const EntityIdList& entityIds, bool deleteDescendants);
|
||||
bool RetrieveAndSortPrefabEntitiesAndInstances(const EntityList& inputEntities, const Instance& commonRootEntityOwningInstance,
|
||||
bool RetrieveAndSortPrefabEntitiesAndInstances(const EntityList& inputEntities, Instance& commonRootEntityOwningInstance,
|
||||
EntityList& outEntities, AZStd::vector<AZStd::unique_ptr<Instance>>& outInstances) const;
|
||||
|
||||
InstanceOptionalReference GetOwnerInstanceByEntityId(AZ::EntityId entityId) const;
|
||||
bool EntitiesBelongToSameInstance(const EntityIdList& entityIds) const;
|
||||
|
||||
/**
|
||||
* Creates a link between the templates of an instance and its parent.
|
||||
*
|
||||
* \param topLevelEntities The list of entities that are immediate children to the container entity of the instance.
|
||||
* \param sourceInstance The instance that corresponds to the source template of the link.
|
||||
* \param targetInstance The id of the target template.
|
||||
* \param undoBatch The undo batch to set as parent for this create link action.
|
||||
* \param commonRootEntityId The id of the entity that the source instance should be parented under.
|
||||
*/
|
||||
void CreateLink(
|
||||
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
|
||||
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId);
|
||||
|
||||
/**
|
||||
* Given a list of entityIds, finds the prefab instance that owns the common root entity of the entityIds.
|
||||
*
|
||||
* \param entityIds The list of entity ids.
|
||||
* \param inputEntityList The list of entities corresponding to the entity ids.
|
||||
* \param topLevelEntities The list of entities that are immediate children of the common root entity.
|
||||
* \param commonRootEntityId The entity id of the common root entity of all the entityIds.
|
||||
* \param commonRootEntityOwningInstance The owning instance of the common root entity.
|
||||
* \return PrefabOperationResult indicating whether the action was successful or not.
|
||||
*/
|
||||
PrefabOperationResult FindCommonRootOwningInstance(
|
||||
const AZStd::vector<AZ::EntityId>& entityIds, EntityList& inputEntityList, EntityList& topLevelEntities,
|
||||
AZ::EntityId& commonRootEntityId, InstanceOptionalReference& commonRootEntityOwningInstance);
|
||||
|
||||
static Instance* GetParentInstance(Instance* instance);
|
||||
static Instance* GetAncestorOfInstanceThatIsChildOfRoot(const Instance* ancestor, Instance* descendant);
|
||||
static void GenerateContainerEntityTransform(const EntityList& topLevelEntities, AZ::Vector3& translation, AZ::Quaternion& rotation);
|
||||
static void EntityIdListToEntityList(const EntityIdList& inputEntityIds, EntityList& outEntities);
|
||||
|
||||
InstanceEntityMapperInterface* m_instanceEntityMapperInterface = nullptr;
|
||||
InstanceToTemplateInterface* m_instanceToTemplateInterface = nullptr;
|
||||
PrefabLoaderInterface* m_prefabLoaderInterface = nullptr;
|
||||
PrefabSystemComponentInterface* m_prefabSystemComponentInterface = nullptr;
|
||||
|
||||
// Caches entity states for undo/redo purposes
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace AzToolsFramework
|
||||
* @param filePath The path for the new prefab file.
|
||||
* @return An outcome object; on failure, it comes with an error message detailing the cause of the error.
|
||||
*/
|
||||
virtual PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZStd::string_view filePath) = 0;
|
||||
virtual PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath) = 0;
|
||||
|
||||
/**
|
||||
* Instantiate a prefab from a prefab file.
|
||||
@@ -58,7 +58,7 @@ namespace AzToolsFramework
|
||||
* @param position The position in world space the prefab should be instantiated in.
|
||||
* @return An outcome object; on failure, it comes with an error message detailing the cause of the error.
|
||||
*/
|
||||
virtual PrefabOperationResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, AZ::Vector3 position) = 0;
|
||||
virtual PrefabOperationResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) = 0;
|
||||
|
||||
/**
|
||||
* Saves changes to prefab to disk.
|
||||
|
||||
@@ -91,8 +91,9 @@ namespace AzToolsFramework
|
||||
m_instanceUpdateExecutor.UpdateTemplateInstancesInQueue();
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<Instance> PrefabSystemComponent::CreatePrefab(const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Instance>>&& instancesToConsume,
|
||||
AZ::IO::PathView filePath, AZStd::unique_ptr<AZ::Entity> containerEntity)
|
||||
AZStd::unique_ptr<Instance> PrefabSystemComponent::CreatePrefab(
|
||||
const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Instance>>&& instancesToConsume,
|
||||
AZ::IO::PathView filePath, AZStd::unique_ptr<AZ::Entity> containerEntity, bool shouldCreateLinks)
|
||||
{
|
||||
AZ::IO::Path relativeFilePath = m_prefabLoader.GetRelativePathToProject(filePath);
|
||||
if (GetTemplateIdFromFilePath(relativeFilePath) != InvalidTemplateId)
|
||||
@@ -104,7 +105,6 @@ namespace AzToolsFramework
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
AZStd::unique_ptr<Instance> newInstance = AZStd::make_unique<Instance>(AZStd::move(containerEntity));
|
||||
|
||||
for (AZ::Entity* entity : entities)
|
||||
@@ -122,8 +122,9 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
newInstance->SetTemplateSourcePath(relativeFilePath);
|
||||
newInstance->SetContainerEntityName(relativeFilePath.Stem().Native());
|
||||
|
||||
TemplateId newTemplateId = CreateTemplateFromInstance(*newInstance);
|
||||
TemplateId newTemplateId = CreateTemplateFromInstance(*newInstance, shouldCreateLinks);
|
||||
if (newTemplateId == InvalidTemplateId)
|
||||
{
|
||||
AZ_Error("Prefab", false,
|
||||
@@ -142,7 +143,6 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabSystemComponent::PropagateTemplateChanges(TemplateId templateId)
|
||||
{
|
||||
UpdatePrefabInstances(templateId);
|
||||
auto templateIdToLinkIdsIterator = m_templateToLinkIdsMap.find(templateId);
|
||||
if (templateIdToLinkIdsIterator != m_templateToLinkIdsMap.end())
|
||||
{
|
||||
@@ -153,15 +153,24 @@ namespace AzToolsFramework
|
||||
templateIdToLinkIdsIterator->second.end()));
|
||||
UpdateLinkedInstances(linkIdsToUpdateQueue);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdatePrefabInstances(templateId);
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabSystemComponent::UpdatePrefabTemplate(TemplateId templateId, const PrefabDom& updatedDom)
|
||||
{
|
||||
PrefabDom& templateDomToUpdate = FindTemplateDom(templateId);
|
||||
if (AZ::JsonSerialization::Compare(templateDomToUpdate, updatedDom) != AZ::JsonSerializerCompareResult::Equal)
|
||||
auto templateToUpdate = FindTemplate(templateId);
|
||||
if (templateToUpdate)
|
||||
{
|
||||
templateDomToUpdate.CopyFrom(updatedDom, templateDomToUpdate.GetAllocator());
|
||||
PropagateTemplateChanges(templateId);
|
||||
PrefabDom& templateDomToUpdate = templateToUpdate->get().GetPrefabDom();
|
||||
if (AZ::JsonSerialization::Compare(templateDomToUpdate, updatedDom) != AZ::JsonSerializerCompareResult::Equal)
|
||||
{
|
||||
templateDomToUpdate.CopyFrom(updatedDom, templateDomToUpdate.GetAllocator());
|
||||
templateToUpdate->get().MarkAsDirty(true);
|
||||
PropagateTemplateChanges(templateId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,6 +261,29 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<Instance> PrefabSystemComponent::InstantiatePrefab(AZ::IO::PathView filePath)
|
||||
{
|
||||
// Retrieve the template id for the source prefab filepath
|
||||
Prefab::TemplateId templateId = GetTemplateIdFromFilePath(filePath);
|
||||
|
||||
if (templateId == Prefab::InvalidTemplateId)
|
||||
{
|
||||
// Load the template from the file
|
||||
templateId = m_prefabLoader.LoadTemplateFromFile(filePath);
|
||||
}
|
||||
|
||||
if (templateId == Prefab::InvalidTemplateId)
|
||||
{
|
||||
AZ_Error("Prefab", false,
|
||||
"Could not load template from path %s during InstantiatePrefab. Unable to proceed",
|
||||
filePath);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return InstantiatePrefab(templateId);
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<Instance> PrefabSystemComponent::InstantiatePrefab(const TemplateId& templateId)
|
||||
{
|
||||
TemplateReference instantiatingTemplate = FindTemplate(templateId);
|
||||
@@ -281,7 +313,7 @@ namespace AzToolsFramework
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
TemplateId PrefabSystemComponent::CreateTemplateFromInstance(Instance& instance)
|
||||
TemplateId PrefabSystemComponent::CreateTemplateFromInstance(Instance& instance, bool shouldCreateLinks)
|
||||
{
|
||||
// We will register the template to match the path the instance has
|
||||
const AZ::IO::Path& templateSourcePath = instance.GetTemplateSourcePath();
|
||||
@@ -315,14 +347,15 @@ namespace AzToolsFramework
|
||||
return InvalidTemplateId;
|
||||
}
|
||||
|
||||
if (!GenerateLinksForNewTemplate(newTemplateId, instance))
|
||||
if (shouldCreateLinks)
|
||||
{
|
||||
// Clear new template and any links associated with it
|
||||
RemoveTemplate(newTemplateId);
|
||||
|
||||
return InvalidTemplateId;
|
||||
if (!GenerateLinksForNewTemplate(newTemplateId, instance))
|
||||
{
|
||||
// Clear new template and any links associated with it
|
||||
RemoveTemplate(newTemplateId);
|
||||
return InvalidTemplateId;
|
||||
}
|
||||
}
|
||||
|
||||
return newTemplateId;
|
||||
}
|
||||
|
||||
@@ -498,12 +531,14 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
Template& sourceTemplate = sourceTemplateReference->get();
|
||||
Template& targetTemplate = targetTemplateReference->get();
|
||||
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
Template& sourceTemplate = sourceTemplateReference->get();
|
||||
AZStd::string_view instanceName(instanceIterator->name.GetString(), instanceIterator->name.GetStringLength());
|
||||
const AZStd::string& targetTemplateFilePath = targetTemplate.GetFilePath().Native();
|
||||
const AZStd::string& sourceTemplateFilePath = sourceTemplate.GetFilePath().Native();
|
||||
#endif
|
||||
|
||||
LinkId newLinkId = CreateUniqueLinkId();
|
||||
Link newLink(newLinkId);
|
||||
@@ -613,7 +648,12 @@ namespace AzToolsFramework
|
||||
instancesValue = memberFound->value;
|
||||
}
|
||||
|
||||
instancesValue->get().AddMember(rapidjson::StringRef(instanceAlias.c_str()), PrefabDomValue(), targetTemplateDom.GetAllocator());
|
||||
// Only add the instance if it's not there already
|
||||
if (instancesValue->get().FindMember(rapidjson::StringRef(instanceAlias.c_str())) == instancesValue->get().MemberEnd())
|
||||
{
|
||||
instancesValue->get().AddMember(
|
||||
rapidjson::StringRef(instanceAlias.c_str()), PrefabDomValue(), targetTemplateDom.GetAllocator());
|
||||
}
|
||||
|
||||
Template& sourceTemplate = sourceTemplateRef->get();
|
||||
|
||||
@@ -731,10 +771,11 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
Template& sourceTemplate = sourceTemplateReference->get();
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
Template& targetTemplate = targetTemplateReference->get();
|
||||
#endif
|
||||
|
||||
AZStd::string_view instanceName(instanceIterator->name.GetString(), instanceIterator->name.GetStringLength());
|
||||
const AZStd::string& targetTemplateFilePath = targetTemplate.GetFilePath().Native();
|
||||
|
||||
link.SetSourceTemplateId(sourceTemplateId);
|
||||
link.SetTargetTemplateId(targetTemplateId);
|
||||
|
||||
@@ -115,9 +115,16 @@ namespace AzToolsFramework
|
||||
*/
|
||||
void RemoveAllTemplates() override;
|
||||
|
||||
/**
|
||||
* Generates a new Prefab Instance based on the Template whose source is stored in filepath.
|
||||
* @param filePath the path to the prefab source file containing the template being instantiated.
|
||||
* @return A unique_ptr to the newly instantiated instance. Null if operation failed.
|
||||
*/
|
||||
AZStd::unique_ptr<Instance> InstantiatePrefab(AZ::IO::PathView filePath) override;
|
||||
|
||||
/**
|
||||
* Generates a new Prefab Instance based on the Template referenced by templateId
|
||||
* @param templateId the id of the template being instantiated
|
||||
* @param templateId the id of the template being instantiated.
|
||||
* @return A unique_ptr to the newly instantiated instance. Null if operation failed.
|
||||
*/
|
||||
AZStd::unique_ptr<Instance> InstantiatePrefab(const TemplateId& templateId) override;
|
||||
@@ -187,17 +194,22 @@ namespace AzToolsFramework
|
||||
* @param entities A vector of entities that will be used in the new instance. May be empty
|
||||
* @param instances A vector of Prefab Instances that will be nested in the new instance, will be consumed and moved.
|
||||
* May be empty
|
||||
* @param filePath the path to associate the template of the new instance to
|
||||
* @param filePath the path to associate the template of the new instance to.
|
||||
* @param containerEntity The container entity for the prefab to be created. It will be created if a nullptr is provided.
|
||||
* @param shouldCreateLinks The flag indicating if links should be created between the templates of the instance
|
||||
* and its nested instances.
|
||||
* @return A pointer to the newly created instance. nullptr on failure
|
||||
*/
|
||||
AZStd::unique_ptr<Instance> CreatePrefab(const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Instance>>&& instancesToConsume,
|
||||
AZ::IO::PathView filePath, AZStd::unique_ptr<AZ::Entity> containerEntity = nullptr) override;
|
||||
AZStd::unique_ptr<Instance> CreatePrefab(
|
||||
const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Instance>>&& instancesToConsume,
|
||||
AZ::IO::PathView filePath, AZStd::unique_ptr<AZ::Entity> containerEntity = nullptr,
|
||||
bool ShouldCreateLinks = true) override;
|
||||
|
||||
PrefabDom& FindTemplateDom(TemplateId templateId) override;
|
||||
|
||||
/**
|
||||
* Updates a template with the given updated DOM.
|
||||
*
|
||||
*
|
||||
* @param templateId The id of the template to update.
|
||||
* @param updatedDom The DOM to update the template with.
|
||||
*/
|
||||
@@ -260,9 +272,11 @@ namespace AzToolsFramework
|
||||
/**
|
||||
* Takes a prefab instance and generates a new Prefab Template
|
||||
* along with any new Prefab Links representing any of the nested instances present
|
||||
* @param instance The instance used to generate the new Template
|
||||
* @param instance The instance used to generate the new Template.
|
||||
* @param shouldCreateLinks The flag indicating if links should be created between the templates of the instance
|
||||
* and its nested instances.
|
||||
*/
|
||||
TemplateId CreateTemplateFromInstance(Instance& instance);
|
||||
TemplateId CreateTemplateFromInstance(Instance& instance, bool shouldCreateLinks);
|
||||
|
||||
/**
|
||||
* Connect two templates with given link, and a nested instance value iterator
|
||||
|
||||
+2
-1
@@ -58,10 +58,11 @@ namespace AzToolsFramework
|
||||
virtual void UpdatePrefabTemplate(TemplateId templateId, const PrefabDom& updatedDom) = 0;
|
||||
virtual void PropagateTemplateChanges(TemplateId templateId) = 0;
|
||||
|
||||
virtual AZStd::unique_ptr<Instance> InstantiatePrefab(AZ::IO::PathView filePath) = 0;
|
||||
virtual AZStd::unique_ptr<Instance> InstantiatePrefab(const TemplateId& templateId) = 0;
|
||||
virtual AZStd::unique_ptr<Instance> CreatePrefab(const AZStd::vector<AZ::Entity*>& entities,
|
||||
AZStd::vector<AZStd::unique_ptr<Instance>>&& instancesToConsume, AZ::IO::PathView filePath,
|
||||
AZStd::unique_ptr<AZ::Entity> containerEntity = nullptr) = 0;
|
||||
AZStd::unique_ptr<AZ::Entity> containerEntity = nullptr, bool ShouldCreateLinks = true) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -35,8 +35,8 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
void PrefabUndoInstance::Capture(
|
||||
PrefabDom& initialState,
|
||||
PrefabDom& endState,
|
||||
const PrefabDom& initialState,
|
||||
const PrefabDom& endState,
|
||||
const TemplateId& templateId)
|
||||
{
|
||||
m_templateId = templateId;
|
||||
@@ -79,13 +79,16 @@ namespace AzToolsFramework
|
||||
|
||||
//generate undo/redo patches
|
||||
m_instanceToTemplateInterface->GeneratePatch(m_redoPatch, initialState, endState);
|
||||
m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(m_redoPatch, entityId);
|
||||
m_instanceToTemplateInterface->GeneratePatch(m_undoPatch, endState, initialState);
|
||||
m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(m_undoPatch, entityId);
|
||||
}
|
||||
|
||||
void PrefabUndoEntityUpdate::Undo()
|
||||
{
|
||||
bool isPatchApplicationSuccessful =
|
||||
m_instanceToTemplateInterface->PatchEntityInTemplate(m_undoPatch, m_entityAlias, m_templateId);
|
||||
[[maybe_unused]] bool isPatchApplicationSuccessful =
|
||||
m_instanceToTemplateInterface->PatchTemplate(m_undoPatch, m_templateId);
|
||||
|
||||
AZ_Error(
|
||||
"Prefab", isPatchApplicationSuccessful,
|
||||
"Applying the undo patch on the entity with alias '%s' in template with id '%llu' was unsuccessful", m_entityAlias.c_str(),
|
||||
@@ -94,8 +97,9 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabUndoEntityUpdate::Redo()
|
||||
{
|
||||
bool isPatchApplicationSuccessful =
|
||||
m_instanceToTemplateInterface->PatchEntityInTemplate(m_redoPatch, m_entityAlias, m_templateId);
|
||||
[[maybe_unused]] bool isPatchApplicationSuccessful =
|
||||
m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId);
|
||||
|
||||
AZ_Error(
|
||||
"Prefab", isPatchApplicationSuccessful,
|
||||
"Applying the redo patch on the entity with alias '%s' in template with id '%llu' was unsuccessful", m_entityAlias.c_str(),
|
||||
@@ -120,7 +124,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& targetId,
|
||||
const TemplateId& sourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
const PrefabDomReference linkDom,
|
||||
PrefabDomReference linkDom,
|
||||
const LinkId linkId)
|
||||
{
|
||||
m_targetId = targetId;
|
||||
|
||||
@@ -51,8 +51,8 @@ namespace AzToolsFramework
|
||||
explicit PrefabUndoInstance(const AZStd::string& undoOperationName);
|
||||
|
||||
void Capture(
|
||||
PrefabDom& initialState,
|
||||
PrefabDom& endState,
|
||||
const PrefabDom& initialState,
|
||||
const PrefabDom& endState,
|
||||
const TemplateId& templateId);
|
||||
|
||||
void Undo() override;
|
||||
@@ -101,7 +101,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& targetId,
|
||||
const TemplateId& sourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
const PrefabDomReference linkDom = PrefabDomReference(),
|
||||
PrefabDomReference linkDom = PrefabDomReference(),
|
||||
const LinkId linkId = InvalidLinkId);
|
||||
|
||||
void Undo() override;
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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 <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabUndo.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Prefab
|
||||
{
|
||||
namespace PrefabUndoHelpers
|
||||
{
|
||||
void UpdatePrefabInstance(
|
||||
const Instance& instance, AZStd::string_view undoMessage, const PrefabDom& instanceDomBeforeUpdate,
|
||||
UndoSystem::URSequencePoint* undoBatch)
|
||||
{
|
||||
PrefabDom instanceDomAfterUpdate;
|
||||
PrefabDomUtils::StoreInstanceInPrefabDom(instance, instanceDomAfterUpdate);
|
||||
|
||||
PrefabUndoInstance* state = aznew Prefab::PrefabUndoInstance(undoMessage);
|
||||
state->Capture(instanceDomBeforeUpdate, instanceDomAfterUpdate, instance.GetTemplateId());
|
||||
state->SetParent(undoBatch);
|
||||
state->Redo();
|
||||
}
|
||||
|
||||
LinkId CreateLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDomReference patch,
|
||||
const InstanceAlias& instanceAlias, UndoSystem::URSequencePoint* undoBatch)
|
||||
{
|
||||
auto linkAddUndo = aznew PrefabUndoInstanceLink("Create Link");
|
||||
linkAddUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, patch, InvalidLinkId);
|
||||
linkAddUndo->SetParent(undoBatch);
|
||||
linkAddUndo->Redo();
|
||||
|
||||
return linkAddUndo->GetLinkId();
|
||||
}
|
||||
|
||||
void RemoveLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias,
|
||||
LinkId linkId, UndoSystem::URSequencePoint* undoBatch)
|
||||
{
|
||||
auto linkRemoveUndo = aznew PrefabUndoInstanceLink("Remove Link");
|
||||
PrefabDom emptyLinkDom;
|
||||
linkRemoveUndo->Capture(
|
||||
targetTemplateId, sourceTemplateId, instanceAlias, emptyLinkDom, linkId);
|
||||
linkRemoveUndo->SetParent(undoBatch);
|
||||
linkRemoveUndo->Redo();
|
||||
}
|
||||
}
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Prefab
|
||||
{
|
||||
namespace PrefabUndoHelpers
|
||||
{
|
||||
void UpdatePrefabInstance(
|
||||
const Instance& instance, AZStd::string_view undoMessage, const PrefabDom& instanceDomBeforeUpdate,
|
||||
UndoSystem::URSequencePoint* undoBatch);
|
||||
LinkId CreateLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDomReference patch,
|
||||
const InstanceAlias& instanceAlias, UndoSystem::URSequencePoint* undoBatch);
|
||||
void RemoveLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias,
|
||||
LinkId linkId, UndoSystem::URSequencePoint* undoBatch);
|
||||
}
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
+1
-1
@@ -41,7 +41,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
}
|
||||
|
||||
prefabProcessorContext.ListPrefabs(
|
||||
[this, &serializeContext, &prefabProcessorContext](AZStd::string_view prefabName, PrefabDom& prefab)
|
||||
[this, &serializeContext, &prefabProcessorContext]([[maybe_unused]] AZStd::string_view prefabName, PrefabDom& prefab)
|
||||
{
|
||||
auto result = RemoveEditorInfo(prefab, serializeContext, prefabProcessorContext);
|
||||
if (!result)
|
||||
|
||||
+1
-1
@@ -34,4 +34,4 @@ namespace AzToolsFramework
|
||||
|
||||
} // namespace AzToolsFramework::Components
|
||||
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -163,7 +163,8 @@ namespace AzToolsFramework
|
||||
QMainWindow* mainWindow = nullptr;
|
||||
for (QWidget* w : qApp->topLevelWidgets())
|
||||
{
|
||||
if (mainWindow = qobject_cast<QMainWindow*>(w))
|
||||
mainWindow = qobject_cast<QMainWindow*>(w);
|
||||
if (mainWindow)
|
||||
{
|
||||
return mainWindow;
|
||||
}
|
||||
|
||||
@@ -74,4 +74,4 @@ namespace AzToolsFramework
|
||||
}
|
||||
} // namespace Internal
|
||||
} // namespace SQLite
|
||||
} // namespace AZFramework
|
||||
} // namespace AZFramework
|
||||
|
||||
@@ -116,4 +116,4 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -95,4 +95,4 @@ namespace AzToolsFramework
|
||||
AZ::DataPatch::FlagsMap m_previousDataFlagsMap;
|
||||
AZ::DataPatch::FlagsMap m_nextDataFlagsMap;
|
||||
};
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -70,4 +70,4 @@ namespace AzToolsFramework
|
||||
};
|
||||
|
||||
using SliceDependencyBrowserNotificationsBus = AZ::EBus<SliceDependencyBrowserNotifications>;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -131,4 +131,4 @@ namespace AzToolsFramework
|
||||
*/
|
||||
bool GetSliceDependendentsByRelativeAssetPath(const AZStd::string& relativePath, AZStd::vector<AZStd::string>& dependents) const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,4 +100,4 @@ namespace AzToolsFramework
|
||||
SliceRelationshipNodeSet m_dependents;
|
||||
SliceRelationshipNodeSet m_dependencies;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2662,7 +2662,7 @@ namespace AzToolsFramework
|
||||
QString cleanAssetSafeFolder(QDir::cleanPath(assetSafeFolder.c_str()));
|
||||
// Compare using clean paths so slash direction does not matter.
|
||||
// Note that this comparison is case sensitive because some file systems
|
||||
// Lumberyard supports are case sensitive.
|
||||
// Open 3D Engine supports are case sensitive.
|
||||
if (cleanSaveAs.startsWith(cleanAssetSafeFolder))
|
||||
{
|
||||
isPathSafeForAssets = true;
|
||||
@@ -4017,8 +4017,8 @@ namespace AzToolsFramework
|
||||
// Detach entities action currently acts on entities and all descendants, so include those as part of the selection
|
||||
AzToolsFramework::EntityIdList selectedDetachEntities(selectedTransformHierarchyEntities.begin(), selectedTransformHierarchyEntities.end());
|
||||
|
||||
// A selection in Lumberyard is usually singular, but a selection can have more than one entity.
|
||||
// No Lumberyard systems support multiple selections, or multiple different groups of selected entities.
|
||||
// A selection in Open 3D Engine is usually singular, but a selection can have more than one entity.
|
||||
// No Open 3D Engine systems support multiple selections, or multiple different groups of selected entities.
|
||||
QString detachEntitiesActionText(QObject::tr("Selection"));
|
||||
QString detachEntitiesTooltipText;
|
||||
if (selectedDetachEntities.size() == 1)
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ namespace AzToolsFramework
|
||||
AZ_Assert(!s_perforceConn, "You may only have one Perforce component.\n");
|
||||
m_shutdownThreadSignal = false;
|
||||
m_waitingOnTrust = false;
|
||||
m_autoChangelistDescription = "*Lumberyard Auto";
|
||||
m_autoChangelistDescription = "*Open 3D Engine Auto";
|
||||
m_connectionState = SourceControlState::Disabled;
|
||||
m_validConnection = false;
|
||||
m_testConnection = false;
|
||||
|
||||
@@ -10,12 +10,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
|
||||
AZ_PUSH_DISABLE_WARNING(4127 4251 4800 4244, "-Wunknown-warning-option") // 4127: conditional expression is constant
|
||||
// 4251: 'QTextCodec::ConverterState::flags': class 'QFlags<QTextCodec::ConversionFlag>' needs to have dll-interface to be used by clients of struct 'QTextCodec::ConverterState'
|
||||
// 4800: 'QTextBoundaryFinderPrivate *const ': forcing value to bool 'true' or 'false' (performance warning)
|
||||
// 4244: conversion from 'int' to 'qint8', possible loss of data
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <QThreadPool>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
namespace AzToolsFramework
|
||||
@@ -80,7 +82,11 @@ namespace AzToolsFramework
|
||||
if (m_state == State::Unloaded)
|
||||
{
|
||||
m_state = State::Loading;
|
||||
QFuture<void> future = QtConcurrent::run([this](){ LoadThread(); });
|
||||
QThreadPool* threadPool;
|
||||
ThumbnailContextRequestBus::BroadcastResult(
|
||||
threadPool,
|
||||
&ThumbnailContextRequestBus::Handler::GetThreadPool);
|
||||
QFuture<void> future = QtConcurrent::run(threadPool, [this](){ LoadThread(); });
|
||||
m_watcher.setFuture(future);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,10 +28,15 @@ namespace AzToolsFramework
|
||||
: m_missingThumbnail(new MissingThumbnail(thumbnailSize))
|
||||
, m_loadingThumbnail(new LoadingThumbnail(thumbnailSize))
|
||||
, m_thumbnailSize(thumbnailSize)
|
||||
, m_threadPool(this)
|
||||
{
|
||||
ThumbnailContextRequestBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
ThumbnailContext::~ThumbnailContext() = default;
|
||||
ThumbnailContext::~ThumbnailContext()
|
||||
{
|
||||
ThumbnailContextRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
bool ThumbnailContext::IsLoading(SharedThumbnailKey key)
|
||||
{
|
||||
@@ -53,6 +58,11 @@ namespace AzToolsFramework
|
||||
AzToolsFramework::AssetBrowser::AssetBrowserViewRequestBus::Broadcast(&AzToolsFramework::AssetBrowser::AssetBrowserViewRequests::Update);
|
||||
}
|
||||
|
||||
QThreadPool* ThumbnailContext::GetThreadPool()
|
||||
{
|
||||
return &m_threadPool;
|
||||
}
|
||||
|
||||
SharedThumbnail ThumbnailContext::GetThumbnail(SharedThumbnailKey key)
|
||||
{
|
||||
SharedThumbnail thumbnail;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QThreadPool>
|
||||
#endif
|
||||
|
||||
class QString;
|
||||
@@ -40,6 +41,7 @@ namespace AzToolsFramework
|
||||
*/
|
||||
class ThumbnailContext
|
||||
: public QObject
|
||||
, public ThumbnailContextRequestBus::Handler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -58,10 +60,13 @@ namespace AzToolsFramework
|
||||
void UnregisterThumbnailProvider(const char* providerName);
|
||||
|
||||
void RedrawThumbnail();
|
||||
|
||||
|
||||
//! Default context used for most thumbnails
|
||||
static constexpr const char* DefaultContext = "Default";
|
||||
|
||||
// ThumbnailContextRequestBus::Handler interface overrides...
|
||||
QThreadPool* GetThreadPool() override;
|
||||
|
||||
private:
|
||||
struct ProviderCompare {
|
||||
bool operator() (const SharedThumbnailProvider& lhs, const SharedThumbnailProvider& rhs) const
|
||||
@@ -79,6 +84,9 @@ namespace AzToolsFramework
|
||||
SharedThumbnail m_loadingThumbnail;
|
||||
//! Thumbnail size (width and height in pixels)
|
||||
int m_thumbnailSize;
|
||||
//! There is only a limited number of threads on global threadPool, because there can be many thumbnails rendering at once
|
||||
//! an individual threadPool is needed to avoid deadlocks
|
||||
QThreadPool m_threadPool;
|
||||
};
|
||||
} // namespace Thumbnailer
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -71,15 +71,12 @@ namespace AzToolsFramework
|
||||
SharedThumbnail thumbnail;
|
||||
ThumbnailerRequestsBus::BroadcastResult(thumbnail, &ThumbnailerRequests::GetThumbnail, m_key, m_contextName.c_str());
|
||||
QPainter painter(this);
|
||||
QPixmap pixmap = thumbnail->GetPixmap();
|
||||
// preserve thumbnail image's ratio, if the widget is wider than the image, center the image hotizontally
|
||||
float aspectRatio = aznumeric_cast<float>(pixmap.width()) / pixmap.height();
|
||||
int originalWidth = width();
|
||||
int originalHeight = height();
|
||||
int realHeight = qMin(aznumeric_cast<int>(originalWidth /aspectRatio), originalHeight);
|
||||
int realWidth = aznumeric_cast<int>(realHeight * aspectRatio);
|
||||
int x = (originalWidth - realWidth) / 2;
|
||||
painter.drawPixmap(QRect(x, 0, realHeight, realWidth), pixmap);
|
||||
|
||||
// Scaling and centering pixmap within bounds to preserve aspect ratio
|
||||
const QPixmap pixmap = thumbnail->GetPixmap().scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
const QSize sizeDelta = size() - pixmap.size();
|
||||
const QPoint pointDelta = QPoint(sizeDelta.width() / 2, sizeDelta.height() / 2);
|
||||
painter.drawPixmap(pointDelta, pixmap);
|
||||
}
|
||||
QWidget::paintEvent(event);
|
||||
}
|
||||
|
||||
@@ -17,11 +17,23 @@
|
||||
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
|
||||
|
||||
class QPixmap;
|
||||
class QThreadPool;
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Thumbnailer
|
||||
{
|
||||
//! Interaction with thumbnail context
|
||||
class ThumbnailContextRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//! Get thread pool for drawing thumbnails
|
||||
virtual QThreadPool* GetThreadPool() = 0;
|
||||
};
|
||||
|
||||
using ThumbnailContextRequestBus = AZ::EBus<ThumbnailContextRequests>;
|
||||
|
||||
//! Interaction with thumbnailer
|
||||
class ThumbnailerRequests
|
||||
: public AZ::EBusTraits
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user