Merge branch 'main' into Spawnable/ProductDependency
This commit is contained in:
@@ -13,6 +13,12 @@
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
struct BehaviorParameter;
|
||||
}
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
@@ -40,6 +46,8 @@ namespace AzToolsFramework
|
||||
};
|
||||
using GlobalFunctionCollection = AZStd::vector<GlobalFunction>;
|
||||
virtual void GetGlobalFunctionList(GlobalFunctionCollection& globalFunctionCollection) const = 0;
|
||||
|
||||
virtual AZStd::string FetchPythonTypeName(const AZ::BehaviorParameter& param) = 0;
|
||||
};
|
||||
|
||||
//! Interface to signal the phases for the Python virtual machine
|
||||
|
||||
@@ -31,6 +31,10 @@ namespace AzToolsFramework
|
||||
//! Allows a component to get the list of selected entities
|
||||
//! \param selectedEntityIds the return vector holding the entities required
|
||||
virtual void GetSelectedEntities(EntityIdList& selectedEntityIds) = 0;
|
||||
|
||||
//! Explicitly sets a component as having been the most recently added.
|
||||
//! This means that the next time the UI refreshes, that component will be ensured to be visible.
|
||||
virtual void SetNewComponentId(AZ::ComponentId componentId) = 0;
|
||||
};
|
||||
|
||||
using EntityPropertyEditorRequestBus = AZ::EBus<EntityPropertyEditorRequests>;
|
||||
|
||||
@@ -761,16 +761,6 @@ namespace AzToolsFramework
|
||||
/// If the view pane was not registered with the ViewPaneOptions.isDeletable set to true, the view pane will be hidden instead.
|
||||
virtual void CloseViewPane(const char* /*paneName*/) {}
|
||||
|
||||
/// Request generation of all level cubemaps.
|
||||
virtual void GenerateAllCubemaps() {}
|
||||
|
||||
/// Regenerate cubemap for a particular entity.
|
||||
/// \param entityId ID of the entity that the cubemap is for
|
||||
/// \param cubemapOutputPath path to a image file to generate
|
||||
/// \param hideEntity Indicates whether the entity should be hidden during cubemap generation. Controls whether the entity's current cubemap output is baked into the new cubemap.
|
||||
virtual void GenerateCubemapForEntity(AZ::EntityId /*entityId*/, AZStd::string* /*cubemapOutputPath*/, bool /*hideEntity*/) {}
|
||||
virtual void GenerateCubemapWithIDForEntity(AZ::EntityId /*entityId*/, AZ::Uuid /*cubemapId*/, AZStd::string* /*cubemapOutputPath*/, bool /*hideEntity*/, bool /*hasCubemapId*/) {}
|
||||
|
||||
//! Spawn asset browser for the appropriate asset types.
|
||||
virtual void BrowseForAssets(AssetBrowser::AssetSelectionModel& /*selection*/) = 0;
|
||||
|
||||
|
||||
@@ -675,20 +675,8 @@ namespace AzToolsFramework
|
||||
// if the new viewport interaction model is enabled we do not want to
|
||||
// filter out locked entities as this breaks with the logic of being
|
||||
// able to select locked entities in the entity outliner
|
||||
if (IsNewViewportInteractionModelEnabled())
|
||||
{
|
||||
selectedEntitiesFiltered.insert(
|
||||
selectedEntitiesFiltered.begin(), selectedEntities.begin(), selectedEntities.end());
|
||||
}
|
||||
else
|
||||
{
|
||||
for (AZ::EntityId nowSelectedId : selectedEntities)
|
||||
{
|
||||
AZ_Assert(nowSelectedId.IsValid(), "Invalid entity Id being marked as selected.");
|
||||
|
||||
selectedEntitiesFiltered.push_back(nowSelectedId);
|
||||
}
|
||||
}
|
||||
selectedEntitiesFiltered.insert(
|
||||
selectedEntitiesFiltered.begin(), selectedEntities.begin(), selectedEntities.end());
|
||||
|
||||
EntityIdList newlySelectedIds;
|
||||
EntityIdList newlyDeselectedIds;
|
||||
|
||||
+4
-9
@@ -10,8 +10,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzCore/Debug/Trace.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Thumbnails/FolderThumbnail.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <QPixmap>
|
||||
@@ -50,8 +50,8 @@ namespace AzToolsFramework
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// FolderThumbnail
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static constexpr const char* FolderIconPath = "Icons/AssetBrowser/Folder_16.svg";
|
||||
static constexpr const char* GemIconPath = "Icons/AssetBrowser/GemFolder_16.svg";
|
||||
static constexpr const char* FolderIconPath = "Assets/Editor/Icons/AssetBrowser/Folder_16.svg";
|
||||
static constexpr const char* GemIconPath = "Assets/Editor/Icons/AssetBrowser/GemFolder_16.svg";
|
||||
|
||||
FolderThumbnail::FolderThumbnail(SharedThumbnailKey key)
|
||||
: Thumbnail(key)
|
||||
@@ -62,13 +62,8 @@ namespace AzToolsFramework
|
||||
auto folderKey = azrtti_cast<const FolderThumbnailKey*>(m_key.data());
|
||||
AZ_Assert(folderKey, "Incorrect key type, excpected FolderThumbnailKey");
|
||||
|
||||
const char* engineRoot = nullptr;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(engineRoot, &AzFramework::ApplicationRequests::GetEngineRoot);
|
||||
AZ_Assert(engineRoot, "Engine Root not initialized");
|
||||
const char* folderIcon = folderKey->IsGem() ? GemIconPath : FolderIconPath;
|
||||
AZStd::string absoluteIconPath;
|
||||
AZ::StringFunc::Path::Join(engineRoot, folderIcon, absoluteIconPath);
|
||||
|
||||
auto absoluteIconPath = AZ::IO::FixedMaxPath(AZ::Utils::GetEnginePath()) / folderIcon;
|
||||
m_pixmap.load(absoluteIconPath.c_str());
|
||||
m_state = m_pixmap.isNull() ? State::Failed : State::Ready;
|
||||
}
|
||||
|
||||
+6
-23
@@ -17,7 +17,7 @@
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/Utils.h>
|
||||
#include <AzCore/std/parallel/thread.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/Asset/AssetBundleManifest.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
@@ -250,7 +250,7 @@ namespace AzToolsFramework
|
||||
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
AZ_Assert(fileIO != nullptr, "AZ::IO::FileIOBase must be ready for use.\n");
|
||||
|
||||
AZStd::string bundleFilePath = assetBundleSettings.m_bundleFilePath;
|
||||
AZ::IO::Path bundleFilePath = AZ::IO::Path(AZStd::string_view{ AZ::Utils::GetEnginePath() }) / assetBundleSettings.m_bundleFilePath;
|
||||
|
||||
AzFramework::PlatformId platformId = static_cast<AzFramework::PlatformId>(AzFramework::PlatformHelper::GetPlatformIndexFromName(assetBundleSettings.m_platform.c_str()));
|
||||
|
||||
@@ -259,22 +259,13 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* appRoot = nullptr;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(appRoot, &AzFramework::ApplicationRequests::GetAppRoot);
|
||||
|
||||
if (AzFramework::StringFunc::Path::IsRelative(bundleFilePath.c_str()))
|
||||
{
|
||||
AzFramework::StringFunc::Path::ConstructFull(appRoot, bundleFilePath.c_str(), bundleFilePath, true);
|
||||
}
|
||||
|
||||
AZ::u64 maxSizeInBytes = static_cast<AZ::u64>(assetBundleSettings.m_maxBundleSizeInMB * NumOfBytesInMB);
|
||||
AZ::u64 assetCatalogFileSizeBuffer = static_cast<AZ::u64>(AssetCatalogFileSizeBufferPercentage * assetBundleSettings.m_maxBundleSizeInMB * NumOfBytesInMB) / 100;
|
||||
AZ::u64 bundleSize = 0;
|
||||
AZ::u64 totalFileSize = 0;
|
||||
int bundleIndex = 0;
|
||||
|
||||
AZStd::string bundleFullPath = bundleFilePath;
|
||||
AZStd::string tempBundleFilePath = bundleFullPath + "_temp";
|
||||
AZStd::string tempBundleFilePath = bundleFilePath.Native() + "_temp";
|
||||
|
||||
AZStd::vector<AZStd::string> dependentBundleNames;
|
||||
AZStd::vector<AZStd::string> levelDirs;
|
||||
@@ -301,7 +292,7 @@ namespace AzToolsFramework
|
||||
if (fileIO->Exists(bundleFilePath.c_str()))
|
||||
{
|
||||
// This will delete both the parent bundle as well as all the dependent bundles mentioned in the manifest file of the parent bundle.
|
||||
if (!DeleteBundleFiles(bundleFilePath))
|
||||
if (!DeleteBundleFiles(bundleFilePath.Native()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -390,7 +381,7 @@ namespace AzToolsFramework
|
||||
// we need to find a bundle which does not exist on disk;
|
||||
bundleIndex++;
|
||||
numOfTries--;
|
||||
dependentBundleFileName = CreateAssetBundleFileName(bundleFilePath, bundleIndex);
|
||||
dependentBundleFileName = CreateAssetBundleFileName(bundleFilePath.Native(), bundleIndex);
|
||||
AzFramework::StringFunc::Path::ReplaceFullName(tempBundleFilePath, (dependentBundleFileName + tempBundleFileSuffix).c_str());
|
||||
} while (numOfTries && fileIO->Exists(tempBundleFilePath.c_str()));
|
||||
|
||||
@@ -463,15 +454,7 @@ namespace AzToolsFramework
|
||||
|
||||
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
|
||||
AZStd::string assetFileInfoListPath = assetBundleSettings.m_assetFileInfoListPath;
|
||||
|
||||
const char* appRoot = nullptr;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(appRoot, &AzFramework::ApplicationRequests::GetAppRoot);
|
||||
|
||||
if (AzFramework::StringFunc::Path::IsRelative(assetFileInfoListPath.c_str()))
|
||||
{
|
||||
AzFramework::StringFunc::Path::ConstructFull(appRoot, assetFileInfoListPath.c_str(), assetFileInfoListPath, true);
|
||||
}
|
||||
AZ::IO::Path assetFileInfoListPath = AZ::IO::Path{ AZStd::string_view{AZ::Utils::GetEnginePath()} } / assetBundleSettings.m_assetFileInfoListPath;
|
||||
|
||||
if (!fileIO->Exists(assetFileInfoListPath.c_str()))
|
||||
{
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
#include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiSystemComponent.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerComponent.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserComponent.h>
|
||||
#include <AzToolsFramework/MaterialBrowser/MaterialBrowserComponent.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemComponent.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
@@ -93,7 +92,6 @@ namespace AzToolsFramework
|
||||
AzToolsFramework::SliceDependencyBrowserComponent::CreateDescriptor(),
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerComponent::CreateDescriptor(),
|
||||
AzToolsFramework::AssetBrowser::AssetBrowserComponent::CreateDescriptor(),
|
||||
AzToolsFramework::MaterialBrowser::MaterialBrowserComponent::CreateDescriptor(),
|
||||
AzToolsFramework::EditorInteractionSystemComponent::CreateDescriptor(),
|
||||
AzToolsFramework::Components::EditorComponentAPIComponent::CreateDescriptor(),
|
||||
AzToolsFramework::Components::EditorLevelComponentAPIComponent::CreateDescriptor(),
|
||||
|
||||
-5
@@ -189,9 +189,6 @@ namespace AzToolsFramework
|
||||
SliceEditorEntityOwnershipServiceNotificationBus::Handler::BusConnect();
|
||||
|
||||
EditorLegacyGameModeNotificationBus::Handler::BusConnect();
|
||||
|
||||
m_entityVisibilityBoundsUnionSystem.Connect();
|
||||
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -199,8 +196,6 @@ namespace AzToolsFramework
|
||||
//=========================================================================
|
||||
void EditorEntityContextComponent::Deactivate()
|
||||
{
|
||||
m_entityVisibilityBoundsUnionSystem.Disconnect();
|
||||
|
||||
EditorLegacyGameModeNotificationBus::Handler::BusDisconnect();
|
||||
|
||||
SliceEditorEntityOwnershipServiceNotificationBus::Handler::BusDisconnect();
|
||||
|
||||
@@ -189,8 +189,6 @@ namespace AzToolsFramework
|
||||
//! EditorEntityContextRequestBus::Events::AddRequiredComponents()
|
||||
AZ::ComponentTypeList m_requiredEditorComponentTypes;
|
||||
|
||||
//! Edit time visibility management integrating entities with the IVisibilitySystem.
|
||||
AzFramework::EntityVisibilityBoundsUnionSystem m_entityVisibilityBoundsUnionSystem;
|
||||
bool m_isLegacySliceService;
|
||||
|
||||
UndoSystem::UndoCacheInterface* m_undoCacheInterface = nullptr;
|
||||
|
||||
@@ -117,8 +117,6 @@ namespace AzToolsFramework
|
||||
{
|
||||
EditorEntityModel::EditorEntityModel()
|
||||
{
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(m_isPrefabEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
EntityCompositionNotificationBus::Handler::BusConnect();
|
||||
EditorOnlyEntityComponentNotificationBus::Handler::BusConnect();
|
||||
EditorEntityRuntimeActivationChangeNotificationBus::Handler::BusConnect();
|
||||
@@ -565,7 +563,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
//retrieve or add an entity entry to the table
|
||||
//the entry must exist, even if not connected, so children and other data can be assigned
|
||||
[[maybe_unused]] auto [it, inserted] = m_entityInfoTable.try_emplace(entityId, m_isPrefabEnabled);
|
||||
[[maybe_unused]] auto [it, inserted] = m_entityInfoTable.try_emplace(entityId);
|
||||
auto& entityInfo = it->second;
|
||||
|
||||
//the entity id defaults to invalid and must be set to match the requested id
|
||||
@@ -882,11 +880,6 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
EditorEntityModel::EditorEntityModelEntry::EditorEntityModelEntry(bool isPrefabEnabled)
|
||||
: m_isPrefabEnabled(isPrefabEnabled)
|
||||
{
|
||||
}
|
||||
|
||||
EditorEntityModel::EditorEntityModelEntry::~EditorEntityModelEntry()
|
||||
{
|
||||
Disconnect();
|
||||
@@ -1213,29 +1206,15 @@ namespace AzToolsFramework
|
||||
auto childItr = m_childIndexCache.find(childId);
|
||||
if (childItr != m_childIndexCache.end())
|
||||
{
|
||||
if (m_isPrefabEnabled)
|
||||
{
|
||||
// Take the last entry and move it into the removed spot instead of deleting the entry and having to move all
|
||||
// following entries one step down.
|
||||
AZ::EntityId backEntity = m_children.back();
|
||||
m_children[childItr->second] = backEntity;
|
||||
// Update cached index for the moved id to the new index.
|
||||
m_childIndexCache[backEntity] = childItr->second;
|
||||
// Now remove the deleted id from the children and cache.
|
||||
m_childIndexCache.erase(childId);
|
||||
m_children.erase(m_children.end() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_children.erase(m_children.begin() + childItr->second);
|
||||
|
||||
// rebuild index cache for faster lookup
|
||||
m_childIndexCache.clear();
|
||||
for (auto childIdToCache : m_children)
|
||||
{
|
||||
m_childIndexCache[childIdToCache] = static_cast<AZ::u64>(m_childIndexCache.size());
|
||||
}
|
||||
}
|
||||
// Take the last entry and move it into the removed spot instead of deleting the entry and having to move all
|
||||
// following entries one step down.
|
||||
AZ::EntityId backEntity = m_children.back();
|
||||
m_children[childItr->second] = backEntity;
|
||||
// Update cached index for the moved id to the new index.
|
||||
m_childIndexCache[backEntity] = childItr->second;
|
||||
// Now remove the deleted id from the children and cache.
|
||||
m_childIndexCache.erase(childId);
|
||||
m_children.erase(m_children.end() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -171,7 +171,6 @@ namespace AzToolsFramework
|
||||
, public PropertyEditorEntityChangeNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
explicit EditorEntityModelEntry(bool isPrefabEnabled);
|
||||
~EditorEntityModelEntry();
|
||||
|
||||
// Separately connect to EditorEntityInfoRequestBus and refresh Entity
|
||||
@@ -336,7 +335,6 @@ namespace AzToolsFramework
|
||||
bool m_visible = true;
|
||||
bool m_locked = false;
|
||||
bool m_connected = false;
|
||||
bool m_isPrefabEnabled = false;
|
||||
AZStd::string m_name;
|
||||
AZStd::string m_sliceAssetName;
|
||||
AZStd::unordered_map<AZ::EntityId, AZ::u64> m_childIndexCache;
|
||||
@@ -375,6 +373,5 @@ namespace AzToolsFramework
|
||||
AZ::EntityId m_postInstantiateBeforeEntity;
|
||||
AZ::EntityId m_postInstantiateSliceParent;
|
||||
bool m_gotInstantiateSliceDetails = false;
|
||||
bool m_isPrefabEnabled = false;
|
||||
};
|
||||
}
|
||||
|
||||
+66
-1
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Script/ScriptSystemBus.h>
|
||||
#include <AzCore/Serialization/Utils.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzFramework/Entity/GameEntityContextBus.h>
|
||||
#include <AzFramework/Spawnable/RootSpawnableInterface.h>
|
||||
@@ -342,6 +343,65 @@ namespace AzToolsFramework
|
||||
m_validateEntitiesCallback = AZStd::move(validateEntitiesCallback);
|
||||
}
|
||||
|
||||
void PrefabEditorEntityOwnershipService::LoadReferencedAssets(AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& referencedAssets)
|
||||
{
|
||||
// Start our loads on all assets by calling GetAsset from the AssetManager
|
||||
for (AZ::Data::Asset<AZ::Data::AssetData>& asset : referencedAssets)
|
||||
{
|
||||
if (!asset.GetId().IsValid())
|
||||
{
|
||||
AZ_Error("Prefab", false, "Invalid asset found referenced in scene while entering game mode");
|
||||
continue;
|
||||
}
|
||||
|
||||
const AZ::Data::AssetLoadBehavior loadBehavior = asset.GetAutoLoadBehavior();
|
||||
|
||||
if (loadBehavior == AZ::Data::AssetLoadBehavior::NoLoad)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AZ::Data::AssetId assetId = asset.GetId();
|
||||
AZ::Data::AssetType assetType = asset.GetType();
|
||||
|
||||
asset = AZ::Data::AssetManager::Instance().GetAsset(assetId, assetType, loadBehavior);
|
||||
|
||||
if (!asset.GetId().IsValid())
|
||||
{
|
||||
AZ_Error("Prefab", false, "Invalid asset found referenced in scene while entering game mode");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// For all Preload assets we block until they're ready
|
||||
// We do this as a seperate pass so that we don't interrupt queuing up all other asset loads
|
||||
for (AZ::Data::Asset<AZ::Data::AssetData>& asset : referencedAssets)
|
||||
{
|
||||
if (!asset.GetId().IsValid())
|
||||
{
|
||||
AZ_Error("Prefab", false, "Invalid asset found referenced in scene while entering game mode");
|
||||
continue;
|
||||
}
|
||||
|
||||
const AZ::Data::AssetLoadBehavior loadBehavior = asset.GetAutoLoadBehavior();
|
||||
|
||||
if (loadBehavior != AZ::Data::AssetLoadBehavior::PreLoad)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
asset.BlockUntilLoadComplete();
|
||||
|
||||
if (asset.IsError())
|
||||
{
|
||||
AZ_Error("Prefab", false, "Asset with id %s failed to preload while entering game mode",
|
||||
asset.GetId().ToString<AZStd::string>().c_str());
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabEditorEntityOwnershipService::StartPlayInEditor()
|
||||
{
|
||||
// This is a workaround until the replacement for GameEntityContext is done
|
||||
@@ -381,16 +441,21 @@ namespace AzToolsFramework
|
||||
rootSpawnableIndex = m_playInEditorData.m_assets.size();
|
||||
}
|
||||
|
||||
LoadReferencedAssets(product.GetReferencedAssets());
|
||||
|
||||
AZ::Data::AssetInfo info;
|
||||
info.m_assetId = product.GetAsset().GetId();
|
||||
info.m_assetType = product.GetAssetType();
|
||||
info.m_relativePath = product.GetId();
|
||||
|
||||
AZ::Data::AssetCatalogRequestBus::Broadcast(
|
||||
&AZ::Data::AssetCatalogRequestBus::Events::RegisterAsset, product.GetAsset().GetId(), info);
|
||||
&AZ::Data::AssetCatalogRequestBus::Events::RegisterAsset, info.m_assetId, info);
|
||||
m_playInEditorData.m_assets.emplace_back(product.ReleaseAsset().release(), AZ::Data::AssetLoadBehavior::Default);
|
||||
}
|
||||
|
||||
// make sure that PRE_NOTIFY assets get their notify before we activate, so that we can preserve the order of
|
||||
// (load asset) -> (notify) -> (init) -> (activate)
|
||||
AZ::Data::AssetManager::Instance().DispatchEvents();
|
||||
|
||||
if (rootSpawnableIndex != NoRootSpawnable)
|
||||
{
|
||||
|
||||
+2
@@ -199,6 +199,8 @@ namespace AzToolsFramework
|
||||
|
||||
void OnEntityRemoved(AZ::EntityId entityId);
|
||||
|
||||
void LoadReferencedAssets(AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& referencedAssets);
|
||||
|
||||
OnEntitiesAddedCallback m_entitiesAddedCallback;
|
||||
OnEntitiesRemovedCallback m_entitiesRemovedCallback;
|
||||
ValidateEntitiesCallback m_validateEntitiesCallback;
|
||||
|
||||
+2
-2
@@ -85,14 +85,14 @@ namespace AzToolsFramework
|
||||
|
||||
// if we're snapping, only increment current radians when we know
|
||||
// preSnapRadians is greater than the angleStep
|
||||
if (snapping)
|
||||
if (snapping && AZStd::abs(angleStepDegrees) > 0.0f)
|
||||
{
|
||||
actionInternal.m_current.m_preSnapRadians += rotationAngleRad * rotateSign;
|
||||
|
||||
const float angleStepRad = AZ::DegToRad(angleStepDegrees);
|
||||
const float preSnapRotateSign = Sign(actionInternal.m_current.m_preSnapRadians);
|
||||
// if we move more than angleStep in a frame, make sure we catch up
|
||||
while (fabsf(actionInternal.m_current.m_preSnapRadians) >= angleStepRad)
|
||||
while (AZStd::abs(actionInternal.m_current.m_preSnapRadians) >= angleStepRad)
|
||||
{
|
||||
actionInternal.m_current.m_radians += angleStepRad * preSnapRotateSign;
|
||||
actionInternal.m_current.m_preSnapRadians -= angleStepRad * preSnapRotateSign;
|
||||
|
||||
+3
-4
@@ -127,8 +127,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
|
||||
worldSurfacePosition, viewportId,
|
||||
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
|
||||
ViewportInteraction::QPointFromScreenPoint(
|
||||
mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates));
|
||||
mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates);
|
||||
|
||||
AZ::Transform worldFromLocal;
|
||||
AZ::TransformBus::EventResult(worldFromLocal, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
|
||||
@@ -402,10 +401,10 @@ namespace AzToolsFramework
|
||||
vertexIndex, localVertex);
|
||||
|
||||
const AZ::Vector3 worldVertex = worldFromLocal.TransformPoint(AZ::AdaptVertexOut<Vertex>(localVertex));
|
||||
const QPoint screenPosition = GetScreenPosition(viewportId, worldVertex);
|
||||
const AzFramework::ScreenPoint screenPosition = GetScreenPosition(viewportId, worldVertex);
|
||||
|
||||
// check if a vertex is inside the box select region
|
||||
if (editorBoxSelect.BoxRegion()->contains(screenPosition))
|
||||
if (editorBoxSelect.BoxRegion()->contains(ViewportInteraction::QPointFromScreenPoint(screenPosition)))
|
||||
{
|
||||
// see if vertexIndex is in active selection
|
||||
auto vertexIt = AZStd::find(
|
||||
|
||||
+3
-6
@@ -103,8 +103,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
|
||||
worldSurfacePosition, interaction.m_interactionId.m_viewportId,
|
||||
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
|
||||
ViewportInteraction::QPointFromScreenPoint(
|
||||
interaction.m_mousePick.m_screenCoordinates));
|
||||
interaction.m_mousePick.m_screenCoordinates);
|
||||
|
||||
m_startInternal = CalculateManipulationDataStart(
|
||||
worldFromLocalUniformScale, worldSurfacePosition, GetLocalPosition(),
|
||||
@@ -129,8 +128,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
|
||||
worldSurfacePosition, interaction.m_interactionId.m_viewportId,
|
||||
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
|
||||
ViewportInteraction::QPointFromScreenPoint(
|
||||
interaction.m_mousePick.m_screenCoordinates));
|
||||
interaction.m_mousePick.m_screenCoordinates);
|
||||
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
|
||||
|
||||
@@ -150,8 +148,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
|
||||
worldSurfacePosition, interaction.m_interactionId.m_viewportId,
|
||||
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
|
||||
ViewportInteraction::QPointFromScreenPoint(
|
||||
interaction.m_mousePick.m_screenCoordinates));
|
||||
interaction.m_mousePick.m_screenCoordinates);
|
||||
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Data
|
||||
{
|
||||
struct AssetId;
|
||||
}
|
||||
}
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace MaterialBrowser
|
||||
{
|
||||
class MaterialBrowserRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
|
||||
// Only a single handler is allowed
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
|
||||
virtual bool HasRecord(const AZ::Data::AssetId& assetId) = 0;
|
||||
virtual bool IsMultiMaterial(const AZ::Data::AssetId& assetId) = 0;
|
||||
};
|
||||
|
||||
using MaterialBrowserRequestBus = AZ::EBus<MaterialBrowserRequests>;
|
||||
} // namespace MaterialBrowser
|
||||
} // namespace AzToolsFramework
|
||||
-65
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
#include <AzToolsFramework/MaterialBrowser/MaterialBrowserComponent.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Thumbnails/FolderThumbnail.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Thumbnails/SourceThumbnail.h>
|
||||
#include <AzToolsFramework/MaterialBrowser/MaterialThumbnail.h>
|
||||
#include <AzToolsFramework/Thumbnails/SourceControlThumbnail.h>
|
||||
|
||||
#include <QApplication>
|
||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: 'QBrush::d': class 'QScopedPointer<QBrushData,QBrushDataPointerDeleter>' needs to have dll-interface to be used by clients of class 'QBrush'
|
||||
#include <QStyle>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace MaterialBrowser
|
||||
{
|
||||
MaterialBrowserComponent::MaterialBrowserComponent()
|
||||
{
|
||||
}
|
||||
|
||||
void MaterialBrowserComponent::Activate()
|
||||
{
|
||||
using namespace Thumbnailer;
|
||||
using namespace AssetBrowser;
|
||||
const char* contextName = "MaterialBrowser";
|
||||
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterContext, contextName);
|
||||
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(FolderThumbnailCache), contextName);
|
||||
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(SourceThumbnailCache), contextName);
|
||||
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(MaterialThumbnailCache), contextName);
|
||||
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(SourceControlThumbnailCache), contextName);
|
||||
}
|
||||
|
||||
void MaterialBrowserComponent::Deactivate()
|
||||
{
|
||||
}
|
||||
|
||||
void MaterialBrowserComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
if (serialize)
|
||||
{
|
||||
serialize->Class<MaterialBrowserComponent, AZ::Component>();
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialBrowserComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
{
|
||||
required.push_back(AZ_CRC("ThumbnailerService", 0x65422b97));
|
||||
}
|
||||
} // namespace MaterialBrowser
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Component/Component.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace MaterialBrowser
|
||||
{
|
||||
//! MaterialBrowserComponent allows initialization of MaterialBrowser systems, such as thumbnails
|
||||
class MaterialBrowserComponent
|
||||
: public AZ::Component
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(MaterialBrowserComponent, "{121F3F3B-2412-490D-9E3E-C205C677F476}")
|
||||
|
||||
MaterialBrowserComponent();
|
||||
virtual ~MaterialBrowserComponent() = default;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AZ::Component
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
|
||||
};
|
||||
} // namespace MaterialBrowser
|
||||
} // namespace AzToolsFramework
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzToolsFramework/MaterialBrowser/MaterialThumbnail.h>
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace MaterialBrowser
|
||||
{
|
||||
static constexpr const char* SimpleMaterialIconPath = ":/MaterialBrowser/images/material_04.png";
|
||||
static constexpr const char* MultiMaterialIconPath = ":/MaterialBrowser/images/material_06.png";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MaterialThumbnail
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
MaterialThumbnail::MaterialThumbnail(Thumbnailer::SharedThumbnailKey key)
|
||||
: Thumbnail(key)
|
||||
{
|
||||
auto productKey = azrtti_cast<const AzToolsFramework::AssetBrowser::ProductThumbnailKey*>(m_key.data());
|
||||
AZ_Assert(productKey, "Incorrect key type, excpected ProductThumbnailKey");
|
||||
|
||||
bool multiMat = false;
|
||||
MaterialBrowserRequestBus::BroadcastResult(multiMat, &MaterialBrowserRequests::IsMultiMaterial, productKey->GetAssetId());
|
||||
|
||||
QString iconPath = multiMat ? MultiMaterialIconPath : SimpleMaterialIconPath;
|
||||
m_pixmap.load(iconPath);
|
||||
m_state = m_pixmap.isNull() ? State::Failed : State::Ready;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MaterialThumbnailCache
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
MaterialThumbnailCache::MaterialThumbnailCache()
|
||||
: ThumbnailCache<MaterialThumbnail, MaterialKeyHash, MaterialKeyEqual>() {}
|
||||
|
||||
MaterialThumbnailCache::~MaterialThumbnailCache() = default;
|
||||
|
||||
int MaterialThumbnailCache::GetPriority() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* MaterialThumbnailCache::GetProviderName() const
|
||||
{
|
||||
return ProviderName;
|
||||
}
|
||||
|
||||
bool MaterialThumbnailCache::IsSupportedThumbnail(Thumbnailer::SharedThumbnailKey key) const
|
||||
{
|
||||
return azrtti_istypeof<const AzToolsFramework::AssetBrowser::ProductThumbnailKey*>(key.data());
|
||||
}
|
||||
|
||||
} // namespace MaterialBrowser
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
#include "MaterialBrowser/moc_MaterialThumbnail.cpp"
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h>
|
||||
#include <AzToolsFramework/MaterialBrowser/MaterialBrowserBus.h>
|
||||
#endif
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace MaterialBrowser
|
||||
{
|
||||
//! Material Browser uses only 2 thumbnails: simple and multimaterial
|
||||
class MaterialThumbnail
|
||||
: public Thumbnailer::Thumbnail
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MaterialThumbnail(Thumbnailer::SharedThumbnailKey key);
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
class MaterialKeyHash
|
||||
{
|
||||
public:
|
||||
size_t operator()(const Thumbnailer::SharedThumbnailKey& /*val*/) const
|
||||
{
|
||||
return 0; // there is only 2 thumbnails in this cache
|
||||
}
|
||||
};
|
||||
|
||||
class MaterialKeyEqual
|
||||
{
|
||||
public:
|
||||
bool operator()(const Thumbnailer::SharedThumbnailKey& val1, const Thumbnailer::SharedThumbnailKey& val2) const
|
||||
{
|
||||
auto productThumbnailKey1 = azrtti_cast<const AzToolsFramework::AssetBrowser::ProductThumbnailKey*>(val1.data());
|
||||
auto productThumbnailKey2 = azrtti_cast<const AzToolsFramework::AssetBrowser::ProductThumbnailKey*>(val2.data());
|
||||
if (!productThumbnailKey1 || !productThumbnailKey2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// check whether keys point to single or multimaterial asset type
|
||||
bool multiMat1 = false;
|
||||
bool multiMat2 = false;
|
||||
MaterialBrowserRequestBus::BroadcastResult(multiMat1, &MaterialBrowserRequests::IsMultiMaterial, productThumbnailKey1->GetAssetId());
|
||||
MaterialBrowserRequestBus::BroadcastResult(multiMat2, &MaterialBrowserRequests::IsMultiMaterial, productThumbnailKey2->GetAssetId());
|
||||
return multiMat1 == multiMat2;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//! MaterialBrowserEntry thumbnails
|
||||
class MaterialThumbnailCache
|
||||
: public Thumbnailer::ThumbnailCache<MaterialThumbnail, MaterialKeyHash, MaterialKeyEqual>
|
||||
{
|
||||
public:
|
||||
MaterialThumbnailCache();
|
||||
~MaterialThumbnailCache() override;
|
||||
|
||||
int GetPriority() const override;
|
||||
const char* GetProviderName() const override;
|
||||
|
||||
static constexpr const char* ProviderName = "CryMaterial Thumbnails";
|
||||
|
||||
protected:
|
||||
bool IsSupportedThumbnail(Thumbnailer::SharedThumbnailKey key) const override;
|
||||
};
|
||||
} // namespace MaterialBrowser
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
|
||||
@@ -11,8 +11,10 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetJsonSerializer.h>
|
||||
#include <AzCore/JSON/prettywriter.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
@@ -115,6 +117,48 @@ namespace AzToolsFramework
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadInstanceFromPrefabDom(
|
||||
Instance& instance, const PrefabDom& prefabDom, AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& referencedAssets, 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)
|
||||
{
|
||||
entityIdMapper.SetEntityIdGenerationApproach(InstanceEntityIdMapper::EntityIdGenerationApproach::Random);
|
||||
}
|
||||
|
||||
AZ::JsonDeserializerSettings settings;
|
||||
// The InstanceEntityIdMapper is registered twice because it's used in several places during deserialization where one is
|
||||
// specific for the InstanceEntityIdMapper and once for the generic JsonEntityIdMapper. Because the Json Serializer's meta
|
||||
// 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<AZ::Data::SerializedAssetTracker>();
|
||||
|
||||
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,
|
||||
"Failed to de-serialize Prefab Instance from Prefab DOM. "
|
||||
"Unable to proceed.");
|
||||
|
||||
return false;
|
||||
}
|
||||
AZ::Data::SerializedAssetTracker* assetTracker = settings.m_metadata.Find<AZ::Data::SerializedAssetTracker>();
|
||||
|
||||
referencedAssets = AZStd::move(assetTracker->GetTrackedAssets());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadInstanceFromPrefabDom(
|
||||
Instance& instance, Instance::EntityList& newlyAddedEntities, const PrefabDom& prefabDom, LoadInstanceFlags flags)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomTypes.h>
|
||||
|
||||
@@ -42,7 +43,7 @@ namespace AzToolsFramework
|
||||
/**
|
||||
* Stores a valid Prefab Instance within a Prefab Dom. Useful for generating Templates
|
||||
* @param instance The instance to store
|
||||
* @param prefabDom the prefabDom that will be used to store the Instance data
|
||||
* @param prefabDom The prefabDom that will be used to store the Instance data
|
||||
* @return bool on whether the operation succeeded
|
||||
*/
|
||||
bool StoreInstanceInPrefabDom(const Instance& instance, PrefabDom& prefabDom);
|
||||
@@ -60,20 +61,32 @@ namespace AzToolsFramework
|
||||
/**
|
||||
* Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances.
|
||||
* @param instance The Instance to load.
|
||||
* @param prefabDom the prefabDom that will be used to load the Instance data.
|
||||
* @param shouldClearContainers whether to clear containers in Instance while loading.
|
||||
* @param prefabDom The prefabDom that will be used to load the Instance data.
|
||||
* @param shouldClearContainers Whether to clear containers in Instance while loading.
|
||||
* @return bool on whether the operation succeeded.
|
||||
*/
|
||||
bool LoadInstanceFromPrefabDom(
|
||||
Instance& instance, const PrefabDom& prefabDom, LoadInstanceFlags flags = LoadInstanceFlags::None);
|
||||
|
||||
/**
|
||||
* Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances.
|
||||
* @param instance The Instance to load.
|
||||
* @param referencedAssets AZ::Assets discovered during json load are added to this list
|
||||
* @param prefabDom The prefabDom that will be used to load the Instance data.
|
||||
* @param shouldClearContainers Whether to clear containers in Instance while loading.
|
||||
* @return bool on whether the operation succeeded.
|
||||
*/
|
||||
bool LoadInstanceFromPrefabDom(
|
||||
Instance& instance, const PrefabDom& prefabDom, AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& referencedAssets,
|
||||
LoadInstanceFlags flags = LoadInstanceFlags::None);
|
||||
|
||||
/**
|
||||
* Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances.
|
||||
* @param instance The Instance to load.
|
||||
* @param newlyAddedEntities The new instances added during deserializing the instance. These are the entities found
|
||||
* in the prefabDom.
|
||||
* @param prefabDom the prefabDom that will be used to load the Instance data.
|
||||
* @param shouldClearContainers whether to clear containers in Instance while loading.
|
||||
* @param prefabDom The prefabDom that will be used to load the Instance data.
|
||||
* @param shouldClearContainers Whether to clear containers in Instance while loading.
|
||||
* @return bool on whether the operation succeeded.
|
||||
*/
|
||||
bool LoadInstanceFromPrefabDom(
|
||||
|
||||
@@ -89,16 +89,14 @@ namespace AzToolsFramework
|
||||
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."));
|
||||
AZStd::string("Could not create a new prefab out of the entities provided - invalid selection."));
|
||||
}
|
||||
|
||||
// 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());
|
||||
RemoveLink(nestedInstance, commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch());
|
||||
}
|
||||
|
||||
PrefabUndoHelpers::UpdatePrefabInstance(
|
||||
@@ -142,9 +140,13 @@ namespace AzToolsFramework
|
||||
// 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);
|
||||
AZ::EntityId topLevelEntityId = topLevelEntity->GetId();
|
||||
if (topLevelEntityId.IsValid())
|
||||
{
|
||||
m_prefabUndoCache.UpdateCache(topLevelEntityId);
|
||||
undoBatch.MarkEntityDirty(topLevelEntityId);
|
||||
AZ::TransformBus::Event(topLevelEntityId, &AZ::TransformBus::Events::SetParent, containerEntityId);
|
||||
}
|
||||
}
|
||||
|
||||
// Select Container Entity
|
||||
@@ -184,6 +186,22 @@ namespace AzToolsFramework
|
||||
instanceToParentUnder = prefabEditorEntityOwnershipInterface->GetRootPrefabInstance();
|
||||
parent = instanceToParentUnder->get().GetContainerEntityId();
|
||||
}
|
||||
|
||||
//Detect whether this instantiation would produce a cyclical dependency
|
||||
auto relativePath = m_prefabLoaderInterface->GetRelativePathToProject(filePath);
|
||||
Prefab::TemplateId templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(relativePath);
|
||||
|
||||
// If the template isn't currently loaded, there's no way for it to be in the hierarchy so we just skip the check.
|
||||
if (templateId != Prefab::InvalidTemplateId && IsPrefabInInstanceAncestorHierarchy(templateId, instanceToParentUnder->get()))
|
||||
{
|
||||
return AZ::Failure(
|
||||
AZStd::string::format(
|
||||
"Instantiate Prefab operation aborted - Cyclical dependency detected\n(%s depends on %s).",
|
||||
relativePath.Native().c_str(),
|
||||
instanceToParentUnder->get().GetTemplateSourcePath().Native().c_str()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
// Initialize Undo Batch object
|
||||
@@ -194,7 +212,7 @@ namespace AzToolsFramework
|
||||
instanceToParentUnderDomBeforeCreate, instanceToParentUnder->get());
|
||||
|
||||
// Instantiate the Prefab
|
||||
auto instanceToCreate = prefabEditorEntityOwnershipInterface->InstantiatePrefab(filePath, instanceToParentUnder);
|
||||
auto instanceToCreate = prefabEditorEntityOwnershipInterface->InstantiatePrefab(relativePath, instanceToParentUnder);
|
||||
|
||||
if (!instanceToCreate)
|
||||
{
|
||||
@@ -223,6 +241,21 @@ namespace AzToolsFramework
|
||||
// Retrieve entityList from entityIds
|
||||
inputEntityList = EntityIdListToEntityList(entityIds);
|
||||
|
||||
// Remove Level Container Entity if it's part of the list
|
||||
AZ::EntityId levelEntityId = GetLevelInstanceContainerEntityId();
|
||||
if (levelEntityId.IsValid())
|
||||
{
|
||||
AZ::Entity* levelEntity = GetEntityById(levelEntityId);
|
||||
if (levelEntity)
|
||||
{
|
||||
auto levelEntityIter = AZStd::find(inputEntityList.begin(), inputEntityList.end(), levelEntity);
|
||||
if (levelEntityIter != inputEntityList.end())
|
||||
{
|
||||
inputEntityList.erase(levelEntityIter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find common root and top level entities
|
||||
bool entitiesHaveCommonRoot = false;
|
||||
|
||||
@@ -238,17 +271,29 @@ namespace AzToolsFramework
|
||||
|
||||
// Retrieve the owning instance of the common root entity, which will be our new instance's parent instance.
|
||||
commonRootEntityOwningInstance = GetOwnerInstanceByEntityId(commonRootEntityId);
|
||||
if (!commonRootEntityOwningInstance)
|
||||
{
|
||||
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"));
|
||||
}
|
||||
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");
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
bool PrefabPublicHandler::IsPrefabInInstanceAncestorHierarchy(TemplateId prefabTemplateId, InstanceOptionalConstReference instance)
|
||||
{
|
||||
InstanceOptionalConstReference currentInstance = instance;
|
||||
|
||||
while (currentInstance.has_value())
|
||||
{
|
||||
if (currentInstance->get().GetTemplateId() == prefabTemplateId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
currentInstance = currentInstance->get().GetParentInstance();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PrefabPublicHandler::CreateLink(
|
||||
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
|
||||
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId)
|
||||
@@ -287,6 +332,34 @@ namespace AzToolsFramework
|
||||
m_prefabUndoCache.Store(containerEntityId, AZStd::move(containerEntityDomAfter));
|
||||
}
|
||||
|
||||
void PrefabPublicHandler::RemoveLink(
|
||||
AZStd::unique_ptr<Instance>& sourceInstance, TemplateId targetTemplateId, UndoSystem::URSequencePoint* undoBatch)
|
||||
{
|
||||
LinkReference nestedInstanceLink = m_prefabSystemComponentInterface->FindLink(sourceInstance->GetLinkId());
|
||||
AZ_Assert(
|
||||
nestedInstanceLink.has_value(),
|
||||
"A valid link was not found for one of the instances provided as input for the CreatePrefab operation.");
|
||||
|
||||
PrefabDomReference nestedInstanceLinkDom = nestedInstanceLink->get().GetLinkDom();
|
||||
AZ_Assert(
|
||||
nestedInstanceLinkDom.has_value(),
|
||||
"A valid DOM was not found for the link corresponding to one of the instances provided as input for the "
|
||||
"CreatePrefab operation.");
|
||||
|
||||
PrefabDomValueReference nestedInstanceLinkPatches =
|
||||
PrefabDomUtils::FindPrefabDomValue(nestedInstanceLinkDom->get(), PrefabDomUtils::PatchesName);
|
||||
AZ_Assert(
|
||||
nestedInstanceLinkPatches.has_value(),
|
||||
"A valid DOM for patches was not found for the link corresponding to one of the instances provided as input for the "
|
||||
"CreatePrefab operation.");
|
||||
|
||||
PrefabDom patchesCopyForUndoSupport;
|
||||
patchesCopyForUndoSupport.CopyFrom(nestedInstanceLinkPatches->get(), patchesCopyForUndoSupport.GetAllocator());
|
||||
PrefabUndoHelpers::RemoveLink(
|
||||
sourceInstance->GetTemplateId(), targetTemplateId, sourceInstance->GetInstanceAlias(), sourceInstance->GetLinkId(),
|
||||
patchesCopyForUndoSupport, undoBatch);
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::SavePrefab(AZ::IO::Path filePath)
|
||||
{
|
||||
auto templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(filePath.c_str());
|
||||
@@ -753,6 +826,11 @@ namespace AzToolsFramework
|
||||
const EntityList& inputEntities, Instance& commonRootEntityOwningInstance,
|
||||
EntityList& outEntities, AZStd::vector<AZStd::unique_ptr<Instance>>& outInstances) const
|
||||
{
|
||||
if (inputEntities.size() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AZStd::queue<AZ::Entity*> entityQueue;
|
||||
|
||||
for (auto inputEntity : inputEntities)
|
||||
@@ -840,7 +918,7 @@ namespace AzToolsFramework
|
||||
outInstances.push_back(AZStd::move(commonRootEntityOwningInstance.DetachNestedInstance(instancePtr->GetInstanceAlias())));
|
||||
}
|
||||
|
||||
return true;
|
||||
return (outEntities.size() + outInstances.size()) > 0;
|
||||
}
|
||||
|
||||
bool PrefabPublicHandler::EntitiesBelongToSameInstance(const EntityIdList& entityIds) const
|
||||
|
||||
@@ -82,6 +82,16 @@ namespace AzToolsFramework
|
||||
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
|
||||
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId);
|
||||
|
||||
/**
|
||||
* Removes the link between template of the sourceInstance and the template corresponding to targetTemplateId.
|
||||
*
|
||||
* \param sourceInstance The instance corresponding to the source template of the link to be removed.
|
||||
* \param targetTemplateId The id of the target template of the link to be removed.
|
||||
* \param undoBatch The undo batch to set as parent for this remove link action.
|
||||
*/
|
||||
void RemoveLink(
|
||||
AZStd::unique_ptr<Instance>& sourceInstance, TemplateId targetTemplateId, UndoSystem::URSequencePoint* undoBatch);
|
||||
|
||||
/**
|
||||
* Given a list of entityIds, finds the prefab instance that owns the common root entity of the entityIds.
|
||||
*
|
||||
@@ -96,6 +106,14 @@ namespace AzToolsFramework
|
||||
const AZStd::vector<AZ::EntityId>& entityIds, EntityList& inputEntityList, EntityList& topLevelEntities,
|
||||
AZ::EntityId& commonRootEntityId, InstanceOptionalReference& commonRootEntityOwningInstance);
|
||||
|
||||
/* Detects whether an instance of prefabTemplateId is present in the hierarchy of ancestors of instance.
|
||||
*
|
||||
* \param prefabTemplateId The template id to test for
|
||||
* \param instance The instance whose ancestor hierarchy prefabTemplateId will be tested against.
|
||||
* \return true if an instance of the template of id prefabTemplateId could be found in the ancestor hierarchy of instance, false otherwise.
|
||||
*/
|
||||
bool IsPrefabInInstanceAncestorHierarchy(TemplateId prefabTemplateId, InstanceOptionalConstReference instance);
|
||||
|
||||
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);
|
||||
|
||||
@@ -663,8 +663,9 @@ namespace AzToolsFramework
|
||||
newLink.SetSourceTemplateId(linkSourceId);
|
||||
newLink.SetInstanceName(instanceAlias.c_str());
|
||||
newLink.GetLinkDom().SetObject();
|
||||
newLink.GetLinkDom().AddMember(rapidjson::StringRef(PrefabDomUtils::SourceName),
|
||||
rapidjson::StringRef(sourceTemplate.GetFilePath().c_str()), newLink.GetLinkDom().GetAllocator());
|
||||
newLink.GetLinkDom().AddMember(
|
||||
rapidjson::StringRef(PrefabDomUtils::SourceName), rapidjson::StringRef(sourceTemplate.GetFilePath().c_str()),
|
||||
newLink.GetLinkDom().GetAllocator());
|
||||
|
||||
if (linkPatch && linkPatch->get().IsArray() && !(linkPatch->get().Empty()))
|
||||
{
|
||||
@@ -720,6 +721,8 @@ namespace AzToolsFramework
|
||||
|
||||
TemplateId PrefabSystemComponent::GetTemplateIdFromFilePath(AZ::IO::PathView filePath) const
|
||||
{
|
||||
AZ_Assert(!filePath.IsAbsolute(), "Prefab - GetTemplateIdFromFilePath was passed an absolute path. Prefabs use paths relative to the project folder.");
|
||||
|
||||
auto found = m_templateFilePathToIdMap.find(filePath);
|
||||
if (found != m_templateFilePathToIdMap.end())
|
||||
{
|
||||
@@ -770,8 +773,8 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
Template& sourceTemplate = sourceTemplateReference->get();
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
Template& sourceTemplate = sourceTemplateReference->get();
|
||||
Template& targetTemplate = targetTemplateReference->get();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace AzToolsFramework
|
||||
, m_sourceId(InvalidTemplateId)
|
||||
, m_instanceAlias("")
|
||||
, m_linkId(InvalidLinkId)
|
||||
, m_linkDom(PrefabDom())
|
||||
, m_linkPatches(PrefabDom())
|
||||
, m_linkStatus(LinkStatus::LINKSTATUS)
|
||||
{
|
||||
m_prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
|
||||
@@ -124,7 +124,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& targetId,
|
||||
const TemplateId& sourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
PrefabDomReference linkDom,
|
||||
PrefabDomReference linkPatches,
|
||||
const LinkId linkId)
|
||||
{
|
||||
m_targetId = targetId;
|
||||
@@ -132,9 +132,9 @@ namespace AzToolsFramework
|
||||
m_instanceAlias = instanceAlias;
|
||||
m_linkId = linkId;
|
||||
|
||||
if (linkDom.has_value())
|
||||
if (linkPatches.has_value())
|
||||
{
|
||||
m_linkDom = AZStd::move(linkDom->get());
|
||||
m_linkPatches = AZStd::move(linkPatches->get());
|
||||
}
|
||||
|
||||
//if linkId is invalid, set as ADD
|
||||
@@ -193,7 +193,7 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabUndoInstanceLink::AddLink()
|
||||
{
|
||||
m_linkId = m_prefabSystemComponentInterface->CreateLink(m_targetId, m_sourceId, m_instanceAlias, m_linkDom, m_linkId);
|
||||
m_linkId = m_prefabSystemComponentInterface->CreateLink(m_targetId, m_sourceId, m_instanceAlias, m_linkPatches, m_linkId);
|
||||
}
|
||||
|
||||
void PrefabUndoInstanceLink::RemoveLink()
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& targetId,
|
||||
const TemplateId& sourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
PrefabDomReference linkDom = PrefabDomReference(),
|
||||
PrefabDomReference linkPatches = PrefabDomReference(),
|
||||
const LinkId linkId = InvalidLinkId);
|
||||
|
||||
void Undo() override;
|
||||
@@ -120,7 +120,7 @@ namespace AzToolsFramework
|
||||
InstanceAlias m_instanceAlias;
|
||||
|
||||
LinkId m_linkId;
|
||||
PrefabDom m_linkDom; //data for delete/update
|
||||
PrefabDom m_linkPatches; //data for delete/update
|
||||
LinkStatus m_linkStatus;
|
||||
|
||||
PrefabSystemComponentInterface* m_prefabSystemComponentInterface = nullptr;
|
||||
|
||||
@@ -46,13 +46,11 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
void RemoveLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias,
|
||||
LinkId linkId, UndoSystem::URSequencePoint* undoBatch)
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias, LinkId linkId,
|
||||
PrefabDomReference linkPatches, UndoSystem::URSequencePoint* undoBatch)
|
||||
{
|
||||
auto linkRemoveUndo = aznew PrefabUndoInstanceLink("Remove Link");
|
||||
PrefabDom emptyLinkDom;
|
||||
linkRemoveUndo->Capture(
|
||||
targetTemplateId, sourceTemplateId, instanceAlias, emptyLinkDom, linkId);
|
||||
linkRemoveUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, linkPatches, linkId);
|
||||
linkRemoveUndo->SetParent(undoBatch);
|
||||
linkRemoveUndo->Redo();
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ namespace AzToolsFramework
|
||||
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);
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias, LinkId linkId,
|
||||
PrefabDomReference linkPatches, UndoSystem::URSequencePoint* undoBatch);
|
||||
}
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
AZStd::move(uniqueName), context.GetSourceUuid(), AZStd::move(serializer));
|
||||
AZ_Assert(spawnable, "Failed to create a new spawnable.");
|
||||
|
||||
bool result = SpawnableUtils::CreateSpawnable(*spawnable, prefab);
|
||||
bool result = SpawnableUtils::CreateSpawnable(*spawnable, prefab, object.GetReferencedAssets());
|
||||
if (result)
|
||||
{
|
||||
AzFramework::Spawnable::EntityList& entities = spawnable->GetEntities();
|
||||
|
||||
+10
@@ -56,6 +56,16 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
return *m_asset;
|
||||
}
|
||||
|
||||
AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& ProcessedObjectStore::GetReferencedAssets()
|
||||
{
|
||||
return m_referencedAssets;
|
||||
}
|
||||
|
||||
const AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& ProcessedObjectStore::GetReferencedAssets() const
|
||||
{
|
||||
return m_referencedAssets;
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<AZ::Data::AssetData> ProcessedObjectStore::ReleaseAsset()
|
||||
{
|
||||
return AZStd::move(m_asset);
|
||||
|
||||
+5
@@ -48,6 +48,10 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
AZ::Data::AssetData& GetAsset();
|
||||
AZStd::unique_ptr<AZ::Data::AssetData> ReleaseAsset();
|
||||
|
||||
AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& GetReferencedAssets();
|
||||
const AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& GetReferencedAssets() const;
|
||||
|
||||
|
||||
const AZStd::string& GetId() const;
|
||||
|
||||
private:
|
||||
@@ -55,6 +59,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
|
||||
SerializerFunction m_assetSerializer;
|
||||
AZStd::unique_ptr<AZ::Data::AssetData> m_asset;
|
||||
AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>> m_referencedAssets;
|
||||
AZStd::string m_uniqueId;
|
||||
};
|
||||
|
||||
|
||||
+9
-2
@@ -28,16 +28,23 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
AzFramework::Spawnable CreateSpawnable(const PrefabDom& prefabDom)
|
||||
{
|
||||
AzFramework::Spawnable spawnable;
|
||||
[[maybe_unused]] bool result = CreateSpawnable(spawnable, prefabDom);
|
||||
AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>> referencedAssets;
|
||||
[[maybe_unused]] bool result = CreateSpawnable(spawnable, prefabDom, referencedAssets);
|
||||
AZ_Assert(result,
|
||||
"Failed to Load Prefab Instance from given Prefab DOM while Spawnable creation.");
|
||||
return spawnable;
|
||||
}
|
||||
|
||||
bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom)
|
||||
{
|
||||
AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>> referencedAssets;
|
||||
return CreateSpawnable(spawnable, prefabDom, referencedAssets);
|
||||
}
|
||||
|
||||
bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom, AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& referencedAssets)
|
||||
{
|
||||
Instance instance;
|
||||
if (Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(instance, prefabDom,
|
||||
if (Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(instance, prefabDom, referencedAssets,
|
||||
Prefab::PrefabDomUtils::LoadInstanceFlags::AssignRandomEntityId)) // Always assign random entity ids because the spawnable is
|
||||
// going to be used to create clones of the entities.
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
{
|
||||
AzFramework::Spawnable CreateSpawnable(const PrefabDom& prefabDom);
|
||||
bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom);
|
||||
bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom, AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& referencedAssets);
|
||||
|
||||
void SortEntitiesByTransformHierarchy(AzFramework::Spawnable& spawnable);
|
||||
} // namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
|
||||
@@ -1353,7 +1353,7 @@ namespace AzToolsFramework
|
||||
// Iterate over the entities left in the instance and if none of them have this
|
||||
// asset entity as its ancestor, then we want to remove it.
|
||||
// \todo - Investigate ways to make this non-linear time. Tricky since removed entities
|
||||
// obviously aren't maintained in any maps. (https://jira.agscollab.com/browse/LY-88218)
|
||||
// obviously aren't maintained in any maps. (LY-88218)
|
||||
bool foundAsAncestor = false;
|
||||
for (const AZ::Entity* instanceEntity : instanceEntities)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzToolsFramework/Thumbnails/LoadingThumbnail.h>
|
||||
#include <AzFramework/Application/Application.h>
|
||||
|
||||
@@ -23,18 +23,14 @@ namespace AzToolsFramework
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// LoadingThumbnail
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static const char* LoadingIconPath = "Icons/AssetBrowser/in_progress.gif";
|
||||
static constexpr const char* LoadingIconPath = "Assets/Editor/Icons/AssetBrowser/in_progress.gif";
|
||||
|
||||
LoadingThumbnail::LoadingThumbnail()
|
||||
: Thumbnail(MAKE_TKEY(ThumbnailKey))
|
||||
, m_angle(0)
|
||||
{
|
||||
const char* engineRoot = nullptr;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(engineRoot, &AzFramework::ApplicationRequests::GetEngineRoot);
|
||||
AZ_Assert(engineRoot, "Engine Root not initialized");
|
||||
AZStd::string iconPath;
|
||||
AZ::StringFunc::Path::Join(engineRoot, LoadingIconPath, iconPath);
|
||||
m_loadingMovie.setFileName(iconPath.c_str());
|
||||
auto absoluteIconPath = AZ::IO::FixedMaxPath(AZ::Utils::GetEnginePath()) / LoadingIconPath;
|
||||
m_loadingMovie.setFileName(absoluteIconPath.c_str());
|
||||
m_loadingMovie.setCacheMode(QMovie::CacheMode::CacheAll);
|
||||
m_loadingMovie.setScaledSize(QSize(LoadingThumbnailSize, LoadingThumbnailSize));
|
||||
m_loadingMovie.start();
|
||||
|
||||
@@ -10,18 +10,21 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzToolsFramework/Thumbnails/MissingThumbnail.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Thumbnailer
|
||||
{
|
||||
static const char* MISSING_ICON_PATH = "Icons/AssetBrowser/Default_16.svg";
|
||||
static constexpr const char* MissingIconPath = "Assets/Editor/Icons/AssetBrowser/Default_16.svg";
|
||||
|
||||
MissingThumbnail::MissingThumbnail()
|
||||
: Thumbnail(MAKE_TKEY(ThumbnailKey))
|
||||
{
|
||||
m_pixmap.load(MISSING_ICON_PATH);
|
||||
auto absoluteIconPath = AZ::IO::FixedMaxPath(AZ::Utils::GetEnginePath()) / MissingIconPath;
|
||||
m_pixmap.load(absoluteIconPath.c_str());
|
||||
m_state = m_pixmap.isNull() ? State::Failed : State::Ready;
|
||||
}
|
||||
|
||||
|
||||
+6
-3
@@ -39,9 +39,10 @@ namespace AzToolsFramework
|
||||
editContext->Class<EditorNonUniformScaleComponent>("Non-uniform Scale",
|
||||
"Non-uniform scale for this entity only (does not propagate through hierarchy)")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Category, "Non-uniform Scale")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(AZ::Edit::Attributes::FixedComponentListIndex, 1)
|
||||
->Attribute(AZ::Edit::Attributes::RemoveableByUser, true)
|
||||
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/NonUniformScale.svg")
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/NonUniformScale.svg")
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::Default, &EditorNonUniformScaleComponent::m_scale, "Non-uniform Scale",
|
||||
"Non-uniform scale for this entity only (does not propagate through hierarchy)")
|
||||
@@ -61,6 +62,8 @@ namespace AzToolsFramework
|
||||
|
||||
void EditorNonUniformScaleComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC_CE("NonUniformScaleService"));
|
||||
|
||||
incompatible.push_back(AZ_CRC_CE("DebugDrawObbService"));
|
||||
incompatible.push_back(AZ_CRC_CE("DebugDrawService"));
|
||||
incompatible.push_back(AZ_CRC_CE("EMotionFXActorService"));
|
||||
|
||||
+82
-5
@@ -25,11 +25,16 @@
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzFramework/Components/TransformComponent.h>
|
||||
#include <AzFramework/Visibility/EntityBoundsUnionBus.h>
|
||||
#include <AzToolsFramework/API/EntityCompositionRequestBus.h>
|
||||
#include <AzToolsFramework/API/EntityPropertyEditorRequestsBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformComponentBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformScalePropertyHandler.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorInspectorComponentBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorPendingCompositionBus.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
|
||||
@@ -261,6 +266,13 @@ namespace AzToolsFramework
|
||||
|
||||
AZ::TransformNotificationBus::Event(
|
||||
GetEntityId(), &TransformNotification::OnTransformChanged, localTM, worldTM);
|
||||
m_transformChangedEvent.Signal(localTM, worldTM);
|
||||
|
||||
AzFramework::IEntityBoundsUnion* boundsUnion = AZ::Interface<AzFramework::IEntityBoundsUnion>::Get();
|
||||
if (boundsUnion != nullptr)
|
||||
{
|
||||
boundsUnion->OnTransformUpdated(GetEntity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -929,15 +941,14 @@ namespace AzToolsFramework
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AZ::Entity* pEntity = nullptr;
|
||||
EBUS_EVENT_RESULT(pEntity, AZ::ComponentApplicationBus, FindEntity, otherEntityId);
|
||||
if (!pEntity)
|
||||
|
||||
AZ::Entity* entity = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->FindEntity(otherEntityId);
|
||||
if (!entity)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return pEntity->FindComponent<TransformComponent>();
|
||||
return entity->FindComponent<TransformComponent>();
|
||||
}
|
||||
|
||||
AZ::TransformInterface* TransformComponent::GetParent()
|
||||
@@ -1196,6 +1207,66 @@ namespace AzToolsFramework
|
||||
destinationComponent->SetWorldTM(const_cast<TransformComponent*>(sourceComponent)->GetWorldTM());
|
||||
}
|
||||
|
||||
AZ::Component* TransformComponent::FindPresentOrPendingComponent(AZ::Uuid componentUuid)
|
||||
{
|
||||
// first check if the component is present and valid
|
||||
if (AZ::Component* foundComponent = GetEntity()->FindComponent(componentUuid))
|
||||
{
|
||||
return foundComponent;
|
||||
}
|
||||
|
||||
// then check to see if there's a component pending because it's in an invalid state
|
||||
AZStd::vector<AZ::Component*> pendingComponents;
|
||||
AzToolsFramework::EditorPendingCompositionRequestBus::Event(GetEntityId(),
|
||||
&AzToolsFramework::EditorPendingCompositionRequests::GetPendingComponents, pendingComponents);
|
||||
|
||||
for (const auto pendingComponent : pendingComponents)
|
||||
{
|
||||
if (pendingComponent->RTTI_IsTypeOf(componentUuid))
|
||||
{
|
||||
return pendingComponent;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool TransformComponent::IsAddNonUniformScaleButtonReadOnly()
|
||||
{
|
||||
return FindPresentOrPendingComponent(EditorNonUniformScaleComponent::TYPEINFO_Uuid()) != nullptr;
|
||||
}
|
||||
|
||||
AZ::Crc32 TransformComponent::OnAddNonUniformScaleButtonPressed()
|
||||
{
|
||||
// if there is already a non-uniform scale component, do nothing
|
||||
if (FindPresentOrPendingComponent(EditorNonUniformScaleComponent::TYPEINFO_Uuid()))
|
||||
{
|
||||
return AZ::Edit::PropertyRefreshLevels::None;
|
||||
}
|
||||
|
||||
const AZStd::vector<AZ::EntityId> entityList = { GetEntityId() };
|
||||
const AZ::ComponentTypeList componentsToAdd = { EditorNonUniformScaleComponent::TYPEINFO_Uuid() };
|
||||
|
||||
AzToolsFramework::EntityCompositionRequests::AddComponentsOutcome addComponentsOutcome;
|
||||
AzToolsFramework::EntityCompositionRequestBus::BroadcastResult(addComponentsOutcome,
|
||||
&AzToolsFramework::EntityCompositionRequests::AddComponentsToEntities, entityList, componentsToAdd);
|
||||
|
||||
const auto nonUniformScaleComponent = FindPresentOrPendingComponent(EditorNonUniformScaleComponent::RTTI_Type());
|
||||
AZ::ComponentId nonUniformScaleComponentId =
|
||||
nonUniformScaleComponent ? nonUniformScaleComponent->GetId() : AZ::InvalidComponentId;
|
||||
|
||||
if (!addComponentsOutcome.IsSuccess() || !nonUniformScaleComponent)
|
||||
{
|
||||
AZ_Warning("Transform component", false, "Failed to add non-uniform scale component.");
|
||||
return AZ::Edit::PropertyRefreshLevels::None;
|
||||
}
|
||||
|
||||
AzToolsFramework::EntityPropertyEditorRequestBus::Broadcast(
|
||||
&AzToolsFramework::EntityPropertyEditorRequests::SetNewComponentId, nonUniformScaleComponentId);
|
||||
|
||||
return AZ::Edit::PropertyRefreshLevels::EntireTree;
|
||||
}
|
||||
|
||||
void TransformComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
// reflect data for script, serialization, editing..
|
||||
@@ -1211,6 +1282,7 @@ namespace AzToolsFramework
|
||||
serializeContext->Class<Components::TransformComponent, EditorComponentBase>()->
|
||||
Field("Parent Entity", &TransformComponent::m_parentEntityId)->
|
||||
Field("Transform Data", &TransformComponent::m_editorTransform)->
|
||||
Field("AddNonUniformScaleButton", &TransformComponent::m_addNonUniformScaleButton)->
|
||||
Field("Cached World Transform", &TransformComponent::m_cachedWorldTransform)->
|
||||
Field("Cached World Transform Parent", &TransformComponent::m_cachedWorldTransformParent)->
|
||||
Field("Parent Activation Transform Mode", &TransformComponent::m_parentActivationTransformMode)->
|
||||
@@ -1224,6 +1296,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
ptrEdit->Class<TransformComponent>("Transform", "Controls the placement of the entity in the world in 3d")->
|
||||
ClassElement(AZ::Edit::ClassElements::EditorData, "")->
|
||||
Attribute(AZ::Edit::Attributes::FixedComponentListIndex, 0)->
|
||||
Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Transform.svg")->
|
||||
Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Transform.png")->
|
||||
Attribute(AZ::Edit::Attributes::AutoExpand, true)->
|
||||
@@ -1234,6 +1307,10 @@ namespace AzToolsFramework
|
||||
DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_editorTransform, "Values", "")->
|
||||
Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::TransformChanged)->
|
||||
Attribute(AZ::Edit::Attributes::AutoExpand, true)->
|
||||
DataElement(AZ::Edit::UIHandlers::Button, &TransformComponent::m_addNonUniformScaleButton, "", "")->
|
||||
Attribute(AZ::Edit::Attributes::ButtonText, "Add non-uniform scale")->
|
||||
Attribute(AZ::Edit::Attributes::ReadOnly, &TransformComponent::IsAddNonUniformScaleButtonReadOnly)->
|
||||
Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::OnAddNonUniformScaleButtonPressed)->
|
||||
DataElement(AZ::Edit::UIHandlers::ComboBox, &TransformComponent::m_parentActivationTransformMode,
|
||||
"Parent activation", "Configures relative transform behavior when parent activates.")->
|
||||
EnumAttribute(AZ::TransformConfig::ParentActivationTransformMode::MaintainOriginalRelativeTransform, "Original relative transform")->
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <AzToolsFramework/API/ComponentEntitySelectionBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Commands/SelectionCommand.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.h>
|
||||
|
||||
#include "EditorComponentBase.h"
|
||||
#include "TransformComponentBus.h"
|
||||
@@ -228,6 +229,10 @@ namespace AzToolsFramework
|
||||
|
||||
void CheckApplyCachedWorldTransform(const AZ::Transform& parentWorld);
|
||||
|
||||
AZ::Component* FindPresentOrPendingComponent(AZ::Uuid componentUuid);
|
||||
bool IsAddNonUniformScaleButtonReadOnly();
|
||||
AZ::Crc32 OnAddNonUniformScaleButtonPressed();
|
||||
|
||||
// Drives transform behavior when parent activates. See AZ::TransformConfig::ParentActivationTransformMode for details.
|
||||
AZ::TransformConfig::ParentActivationTransformMode m_parentActivationTransformMode;
|
||||
|
||||
@@ -260,6 +265,10 @@ namespace AzToolsFramework
|
||||
bool m_worldTransformDirty = true;
|
||||
bool m_isStatic = false;
|
||||
|
||||
// This is a workaround for a bug which causes the button to appear with incorrect placement if a UI
|
||||
// element is used rather than a data element.
|
||||
bool m_addNonUniformScaleButton = false;
|
||||
|
||||
// Deprecated
|
||||
AZ::InterpolationMode m_interpolatePosition;
|
||||
AZ::InterpolationMode m_interpolateRotation;
|
||||
|
||||
+32
-19
@@ -151,32 +151,36 @@ namespace AzToolsFramework
|
||||
{
|
||||
if (!selectedEntities.empty())
|
||||
{
|
||||
bool layerInSelection = false;
|
||||
|
||||
for (AZ::EntityId entityId : selectedEntities)
|
||||
// Hide if the only selected entity is the Level Container
|
||||
if (selectedEntities.size() > 1 || !s_prefabPublicInterface->IsLevelInstanceContainerEntity(selectedEntities[0]))
|
||||
{
|
||||
if (!layerInSelection)
|
||||
{
|
||||
AzToolsFramework::Layers::EditorLayerComponentRequestBus::EventResult(
|
||||
layerInSelection, entityId,
|
||||
&AzToolsFramework::Layers::EditorLayerComponentRequestBus::Events::HasLayer);
|
||||
bool layerInSelection = false;
|
||||
|
||||
if (layerInSelection)
|
||||
for (AZ::EntityId entityId : selectedEntities)
|
||||
{
|
||||
if (!layerInSelection)
|
||||
{
|
||||
break;
|
||||
AzToolsFramework::Layers::EditorLayerComponentRequestBus::EventResult(
|
||||
layerInSelection, entityId,
|
||||
&AzToolsFramework::Layers::EditorLayerComponentRequestBus::Events::HasLayer);
|
||||
|
||||
if (layerInSelection)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Layers can't be in prefabs.
|
||||
if (!layerInSelection)
|
||||
{
|
||||
QAction* createAction = menu->addAction(QObject::tr("Create Prefab..."));
|
||||
createAction->setToolTip(QObject::tr("Creates a prefab out of the currently selected entities."));
|
||||
// Layers can't be in prefabs.
|
||||
if (!layerInSelection)
|
||||
{
|
||||
QAction* createAction = menu->addAction(QObject::tr("Create Prefab..."));
|
||||
createAction->setToolTip(QObject::tr("Creates a prefab out of the currently selected entities."));
|
||||
|
||||
QObject::connect(createAction, &QAction::triggered, createAction, [this, selectedEntities] {
|
||||
ContextMenu_CreatePrefab(selectedEntities);
|
||||
});
|
||||
QObject::connect(createAction, &QAction::triggered, createAction, [this, selectedEntities] {
|
||||
ContextMenu_CreatePrefab(selectedEntities);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -272,6 +276,15 @@ namespace AzToolsFramework
|
||||
QWidget* activeWindow = QApplication::activeWindow();
|
||||
const AZStd::string prefabFilesPath = "@devassets@/Prefabs";
|
||||
|
||||
// Remove Level entity if it's part of the list
|
||||
|
||||
auto levelContainerIter =
|
||||
AZStd::find(selectedEntities.begin(), selectedEntities.end(), s_prefabPublicInterface->GetLevelInstanceContainerEntityId());
|
||||
if (levelContainerIter != selectedEntities.end())
|
||||
{
|
||||
selectedEntities.erase(levelContainerIter);
|
||||
}
|
||||
|
||||
// Set default folder for prefabs
|
||||
AZ::IO::FileIOBase* fileIoBaseInstance = AZ::IO::FileIOBase::GetInstance();
|
||||
|
||||
|
||||
+83
-13
@@ -63,6 +63,7 @@ AZ_POP_DISABLE_WARNING
|
||||
#include <AzToolsFramework/ToolsComponents/EditorOnlyEntityComponentBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorOnlyEntityComponent.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorLayerComponent.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.h>
|
||||
#include <AzToolsFramework/ToolsMessaging/EntityHighlightBus.h>
|
||||
#include <AzToolsFramework/UI/ComponentPalette/ComponentPaletteUtil.hxx>
|
||||
#include <AzToolsFramework/UI/ComponentPalette/ComponentPaletteWidget.hxx>
|
||||
@@ -334,6 +335,7 @@ namespace AzToolsFramework
|
||||
m_gui->m_entityDetailsLabel->setObjectName("LabelEntityDetails");
|
||||
m_gui->m_entitySearchBox->setReadOnly(false);
|
||||
m_gui->m_entitySearchBox->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_gui->m_entitySearchBox->setClearButtonEnabled(true);
|
||||
AzQtComponents::LineEdit::applySearchStyle(m_gui->m_entitySearchBox);
|
||||
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
@@ -494,6 +496,11 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
void EntityPropertyEditor::SetNewComponentId(AZ::ComponentId componentId)
|
||||
{
|
||||
m_newComponentId = componentId;
|
||||
}
|
||||
|
||||
void EntityPropertyEditor::SetOverrideEntityIds(const AzToolsFramework::EntityIdSet& entities)
|
||||
{
|
||||
m_overrideSelectedEntityIds = entities;
|
||||
@@ -1039,15 +1046,23 @@ namespace AzToolsFramework
|
||||
sortedComponents.end(),
|
||||
[=](const OrderedSortComponentEntry& component1, const OrderedSortComponentEntry& component2)
|
||||
{
|
||||
// Transform component must be first, always
|
||||
// If component 1 is a transform component, it is sorted earlier
|
||||
if (component1.m_component->RTTI_IsTypeOf(AZ::EditorTransformComponentTypeId))
|
||||
AZStd::optional<int> fixedComponentListIndex1 = GetFixedComponentListIndex(component1.m_component);
|
||||
AZStd::optional<int> fixedComponentListIndex2 = GetFixedComponentListIndex(component2.m_component);
|
||||
|
||||
// If both components have fixed list indices, sort based on those indices
|
||||
if (fixedComponentListIndex1.has_value() && fixedComponentListIndex2.has_value())
|
||||
{
|
||||
return fixedComponentListIndex1.value() < fixedComponentListIndex2.value();
|
||||
}
|
||||
|
||||
// If component 1 has a fixed list index, sort it first
|
||||
if (fixedComponentListIndex1.has_value())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If component 2 is a transform component, component 1 is never sorted earlier
|
||||
if (component2.m_component->RTTI_IsTypeOf(AZ::EditorTransformComponentTypeId))
|
||||
// If component 2 has a fixed list index, component 1 should not be sorted before it
|
||||
if (fixedComponentListIndex2.has_value())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1128,10 +1143,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
if (auto attributeData = azdynamic_cast<AZ::Edit::AttributeData<bool>*>(attribute))
|
||||
{
|
||||
if (!attributeData->Get(nullptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return attributeData->Get(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1166,6 +1178,36 @@ namespace AzToolsFramework
|
||||
return true;
|
||||
}
|
||||
|
||||
AZStd::optional<int> EntityPropertyEditor::GetFixedComponentListIndex(const AZ::Component* component)
|
||||
{
|
||||
auto componentClassData = component ? GetComponentClassData(component) : nullptr;
|
||||
if (componentClassData && componentClassData->m_editData)
|
||||
{
|
||||
if (auto editorDataElement = componentClassData->m_editData->FindElementData(AZ::Edit::ClassElements::EditorData))
|
||||
{
|
||||
if (auto attribute = editorDataElement->FindAttribute(AZ::Edit::Attributes::FixedComponentListIndex))
|
||||
{
|
||||
if (auto attributeData = azdynamic_cast<AZ::Edit::AttributeData<int>*>(attribute))
|
||||
{
|
||||
return { attributeData->Get(nullptr) };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool EntityPropertyEditor::IsComponentDraggable(const AZ::Component* component)
|
||||
{
|
||||
return !GetFixedComponentListIndex(component).has_value();
|
||||
}
|
||||
|
||||
bool EntityPropertyEditor::AreComponentsDraggable(const AZ::Entity::ComponentArrayType& components) const
|
||||
{
|
||||
return AZStd::all_of(
|
||||
components.begin(), components.end(), [](AZ::Component* component) { return IsComponentDraggable(component); });
|
||||
}
|
||||
|
||||
bool EntityPropertyEditor::AreComponentsCopyable(const AZ::Entity::ComponentArrayType& components) const
|
||||
{
|
||||
return AreComponentsCopyable(components, m_componentFilter);
|
||||
@@ -3367,7 +3409,9 @@ namespace AzToolsFramework
|
||||
sourceComponents.size() == m_selectedEntityIds.size() &&
|
||||
targetComponents.size() == m_selectedEntityIds.size() &&
|
||||
AreComponentsRemovable(sourceComponents) &&
|
||||
AreComponentsRemovable(targetComponents);
|
||||
AreComponentsRemovable(targetComponents) &&
|
||||
AreComponentsDraggable(sourceComponents) &&
|
||||
AreComponentsDraggable(targetComponents);
|
||||
}
|
||||
|
||||
bool EntityPropertyEditor::IsMoveComponentsUpAllowed() const
|
||||
@@ -3681,14 +3725,38 @@ namespace AzToolsFramework
|
||||
|
||||
void EntityPropertyEditor::ScrollToNewComponent()
|
||||
{
|
||||
//force new components to be visible, assuming they are added to the end of the list and layout
|
||||
auto componentEditor = GetComponentEditorsFromIndex(m_componentEditorsUsed - 1);
|
||||
// force new components to be visible
|
||||
// if no component has been explicitly set at the most recently added,
|
||||
// assume new components are added to the end of the list and layout
|
||||
AZ::s32 newComponentIndex = m_componentEditorsUsed - 1;
|
||||
|
||||
// if there is a component id explicitly set as the most recently added, try to find it and make sure it is visible
|
||||
if (m_newComponentId.has_value() && m_newComponentId.value() != AZ::InvalidComponentId)
|
||||
{
|
||||
AZ::ComponentId newComponentId = m_newComponentId.value();
|
||||
for (AZ::s32 componentIndex = 0; componentIndex < m_componentEditorsUsed; ++componentIndex)
|
||||
{
|
||||
if (m_componentEditors[componentIndex])
|
||||
{
|
||||
for (const auto component : m_componentEditors[componentIndex]->GetComponents())
|
||||
{
|
||||
if (component->GetId() == newComponentId)
|
||||
{
|
||||
newComponentIndex = componentIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto componentEditor = GetComponentEditorsFromIndex(newComponentIndex);
|
||||
if (componentEditor)
|
||||
{
|
||||
m_gui->m_componentList->ensureWidgetVisible(componentEditor);
|
||||
}
|
||||
m_shouldScrollToNewComponents = false;
|
||||
m_shouldScrollToNewComponentsQueued = false;
|
||||
m_newComponentId.reset();
|
||||
}
|
||||
|
||||
void EntityPropertyEditor::QueueScrollToNewComponent()
|
||||
@@ -4073,7 +4141,8 @@ namespace AzToolsFramework
|
||||
{
|
||||
if (!componentEditor ||
|
||||
!componentEditor->isVisible() ||
|
||||
!AreComponentsRemovable(componentEditor->GetComponents()))
|
||||
!AreComponentsRemovable(componentEditor->GetComponents()) ||
|
||||
!AreComponentsDraggable(componentEditor->GetComponents()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -4223,6 +4292,7 @@ namespace AzToolsFramework
|
||||
while (targetComponentEditor
|
||||
&& (targetComponentEditor->IsDragged()
|
||||
|| !AreComponentsRemovable(targetComponentEditor->GetComponents())
|
||||
|| !AreComponentsDraggable(targetComponentEditor->GetComponents())
|
||||
|| (globalRect.center().y() > GetWidgetGlobalRect(targetComponentEditor).center().y())))
|
||||
{
|
||||
if (targetItr == m_componentEditors.end() || targetComponentEditor == m_componentEditors.back() || !targetComponentEditor->isVisible())
|
||||
|
||||
+7
@@ -211,6 +211,7 @@ namespace AzToolsFramework
|
||||
// EntityPropertEditorRequestBus
|
||||
void GetSelectedAndPinnedEntities(EntityIdList& selectedEntityIds) override;
|
||||
void GetSelectedEntities(EntityIdList& selectedEntityIds) override;
|
||||
void SetNewComponentId(AZ::ComponentId componentId) override;
|
||||
|
||||
bool IsEntitySelected(const AZ::EntityId& id) const;
|
||||
bool IsSingleEntitySelected(const AZ::EntityId& id) const;
|
||||
@@ -237,6 +238,9 @@ namespace AzToolsFramework
|
||||
static bool DoesComponentPassFilter(const AZ::Component* component, const ComponentFilter& filter);
|
||||
static bool IsComponentRemovable(const AZ::Component* component);
|
||||
bool AreComponentsRemovable(const AZ::Entity::ComponentArrayType& components) const;
|
||||
static AZStd::optional<int> GetFixedComponentListIndex(const AZ::Component* component);
|
||||
static bool IsComponentDraggable(const AZ::Component* component);
|
||||
bool AreComponentsDraggable(const AZ::Entity::ComponentArrayType& components) const;
|
||||
bool AreComponentsCopyable(const AZ::Entity::ComponentArrayType& components) const;
|
||||
|
||||
void AddMenuOptionsForComponents(QMenu& menu, const QPoint& position);
|
||||
@@ -568,6 +572,9 @@ namespace AzToolsFramework
|
||||
void ConnectToEntityBuses(const AZ::EntityId& entityId);
|
||||
void DisconnectFromEntityBuses(const AZ::EntityId& entityId);
|
||||
|
||||
//! Stores a component id to be focused on next time the UI updates.
|
||||
AZStd::optional<AZ::ComponentId> m_newComponentId;
|
||||
|
||||
private slots:
|
||||
void OnPropertyRefreshRequired(); // refresh is needed for a property.
|
||||
void UpdateContents();
|
||||
|
||||
+10
-16
@@ -121,17 +121,14 @@ namespace AzToolsFramework
|
||||
EditorPickModeRequestBus::Handler::BusConnect(pickModeEntityContextId);
|
||||
EditorEventsBus::Handler::BusConnect();
|
||||
|
||||
if (IsNewViewportInteractionModelEnabled())
|
||||
// replace the default input handler with one specific for dealing with
|
||||
// entity selection in the viewport
|
||||
EditorInteractionSystemViewportSelectionRequestBus::Event(
|
||||
GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetHandler,
|
||||
[](const EditorVisibleEntityDataCache* entityDataCache)
|
||||
{
|
||||
// replace the default input handler with one specific for dealing with
|
||||
// entity selection in the viewport
|
||||
EditorInteractionSystemViewportSelectionRequestBus::Event(
|
||||
GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetHandler,
|
||||
[](const EditorVisibleEntityDataCache* entityDataCache)
|
||||
{
|
||||
return AZStd::make_unique<EditorPickEntitySelection>(entityDataCache);
|
||||
});
|
||||
}
|
||||
return AZStd::make_unique<EditorPickEntitySelection>(entityDataCache);
|
||||
});
|
||||
|
||||
if (!pickModeEntityContextId.IsNull())
|
||||
{
|
||||
@@ -162,12 +159,9 @@ namespace AzToolsFramework
|
||||
EditorEventsBus::Handler::BusDisconnect();
|
||||
emit OnPickComplete();
|
||||
|
||||
if (IsNewViewportInteractionModelEnabled())
|
||||
{
|
||||
// return to the default viewport editor selection
|
||||
EditorInteractionSystemViewportSelectionRequestBus::Event(
|
||||
GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetDefaultHandler);
|
||||
}
|
||||
// return to the default viewport editor selection
|
||||
EditorInteractionSystemViewportSelectionRequestBus::Event(
|
||||
GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetDefaultHandler);
|
||||
|
||||
EditorPickModeNotificationBus::Broadcast(&EditorPickModeNotifications::OnEntityPickModeStopped);
|
||||
}
|
||||
|
||||
-12
@@ -126,7 +126,6 @@ namespace UnitTest
|
||||
/// Base fixture for ToolsApplication editor tests.
|
||||
class ToolsApplicationFixture
|
||||
: public AllocatorsTestFixture
|
||||
, private AzToolsFramework::NewViewportInteractionModelEnabledRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
void SetUp() override final
|
||||
@@ -148,8 +147,6 @@ namespace UnitTest
|
||||
// in the unit tests.
|
||||
AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
|
||||
|
||||
AzToolsFramework::NewViewportInteractionModelEnabledRequestBus::Handler::BusConnect();
|
||||
|
||||
m_editorActions.Connect();
|
||||
|
||||
const auto viewportHandlerBuilder =
|
||||
@@ -184,7 +181,6 @@ namespace UnitTest
|
||||
|
||||
TearDownEditorFixtureImpl();
|
||||
m_editorActions.Disconnect();
|
||||
AzToolsFramework::NewViewportInteractionModelEnabledRequestBus::Handler::BusDisconnect();
|
||||
|
||||
// Stop & delete the Application created by this fixture, hence not using GetApplication() here
|
||||
if (m_app)
|
||||
@@ -222,14 +218,6 @@ namespace UnitTest
|
||||
|
||||
private:
|
||||
AZStd::unique_ptr<ToolsTestApplication> m_app;
|
||||
|
||||
// NewViewportInteractionModelEnabledRequestBus ...
|
||||
bool IsNewViewportInteractionModelEnabled() override
|
||||
{
|
||||
// default to the new viewport interaction model bus being enabled so the
|
||||
// manipulator manager is correctly instantiated in EditorDefaultSelection
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class EditorEntityComponentChangeDetector
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportTypes.h>
|
||||
|
||||
class QPoint; // LYN-2315 in-progress, remove this
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
struct ScreenPoint;
|
||||
@@ -167,19 +165,37 @@ namespace AzToolsFramework
|
||||
/// Return the angle snapping/step size.
|
||||
virtual float AngleStep() = 0;
|
||||
/// Transform a point in world space to screen space coordinates.
|
||||
virtual QPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition) = 0;
|
||||
virtual AzFramework::ScreenPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition) = 0;
|
||||
/// Transform a point in screen space coordinates to a vector in world space based on clip space depth.
|
||||
/// Depth specifies a relative camera depth to project in the range of [0.f, 1.f].
|
||||
/// Returns the world space position if successful.
|
||||
virtual AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const QPoint& screenPosition, float depth) = 0;
|
||||
virtual AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const AzFramework::ScreenPoint& screenPosition, float depth) = 0;
|
||||
/// Casts a point in screen space to a ray in world space originating from the viewport camera frustum's near plane.
|
||||
/// Returns a ray containing the ray's origin and a direction normal, if successful.
|
||||
virtual AZStd::optional<ProjectedViewportRay> ViewportScreenToWorldRay(const QPoint& screenPosition) = 0;
|
||||
virtual AZStd::optional<ProjectedViewportRay> ViewportScreenToWorldRay(const AzFramework::ScreenPoint& screenPosition) = 0;
|
||||
|
||||
protected:
|
||||
~ViewportInteractionRequests() = default;
|
||||
};
|
||||
|
||||
/// Interface to return only viewport specific settings (e.g. snapping).
|
||||
class ViewportSettings
|
||||
{
|
||||
public:
|
||||
virtual ~ViewportSettings() = default;
|
||||
|
||||
/// Return if grid snapping is enabled.
|
||||
virtual bool GridSnappingEnabled() const = 0;
|
||||
/// Return the grid snapping size.
|
||||
virtual float GridSize() const = 0;
|
||||
/// Does the grid currently want to be displayed.
|
||||
virtual bool ShowGrid() const = 0;
|
||||
/// Return if angle snapping is enabled.
|
||||
virtual bool AngleSnappingEnabled() const = 0;
|
||||
/// Return the angle snapping/step size.
|
||||
virtual float AngleStep() const = 0;
|
||||
};
|
||||
|
||||
/// Type to inherit to implement ViewportInteractionRequests.
|
||||
using ViewportInteractionRequestBus = AZ::EBus<ViewportInteractionRequests, ViewportEBusTraits>;
|
||||
|
||||
@@ -207,9 +223,9 @@ namespace AzToolsFramework
|
||||
public:
|
||||
/// Given a point in screen space, return the picked entity (if any).
|
||||
/// Picked EntityId will be returned, InvalidEntityId will be returned on failure.
|
||||
virtual AZ::EntityId PickEntity(const QPoint& point) = 0;
|
||||
virtual AZ::EntityId PickEntity(const AzFramework::ScreenPoint& point) = 0;
|
||||
/// Given a point in screen space, return the terrain position in world space.
|
||||
virtual AZ::Vector3 PickTerrain(const QPoint& point) = 0;
|
||||
virtual AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) = 0;
|
||||
/// Return the terrain height given a world position in 2d (xy plane).
|
||||
virtual float TerrainHeight(const AZ::Vector2& position) = 0;
|
||||
/// Given the current view frustum (viewport) return all visible entities.
|
||||
@@ -246,6 +262,8 @@ namespace AzToolsFramework
|
||||
/// from ViewportCursorScreenPosition. This method will always return the correct position to generate a mouse
|
||||
/// position delta.
|
||||
virtual AZStd::optional<AzFramework::ScreenPoint> PreviousViewportCursorScreenPosition() = 0;
|
||||
/// Is mouse over viewport.
|
||||
virtual bool IsMouseOver() const = 0;
|
||||
|
||||
protected:
|
||||
~ViewportMouseCursorRequests() = default;
|
||||
@@ -277,20 +295,6 @@ namespace AzToolsFramework
|
||||
|
||||
} // namespace ViewportInteraction
|
||||
|
||||
/// Temporary bus to query if the new Viewport Interaction Model mode is enabled or not.
|
||||
class NewViewportInteractionModelEnabledRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
virtual bool IsNewViewportInteractionModelEnabled() = 0;
|
||||
|
||||
protected:
|
||||
~NewViewportInteractionModelEnabledRequests() = default;
|
||||
};
|
||||
|
||||
/// Type to inherit to implement NewViewportInteractionModelEnabledRequests
|
||||
using NewViewportInteractionModelEnabledRequestBus = AZ::EBus<NewViewportInteractionModelEnabledRequests>;
|
||||
|
||||
/// Utility function to return EntityContextId.
|
||||
inline AzFramework::EntityContextId GetEntityContextId()
|
||||
{
|
||||
@@ -300,16 +304,4 @@ namespace AzToolsFramework
|
||||
|
||||
return entityContextId;
|
||||
}
|
||||
|
||||
/// Utility function to return if the new Viewport Interaction Model
|
||||
/// is enabled (wraps NewViewportInteractionModelEnabledRequests).
|
||||
inline bool IsNewViewportInteractionModelEnabled()
|
||||
{
|
||||
bool newViewportInteractionModelEnabled = false;
|
||||
NewViewportInteractionModelEnabledRequestBus::BroadcastResult(
|
||||
newViewportInteractionModelEnabled,
|
||||
&NewViewportInteractionModelEnabledRequests::IsNewViewportInteractionModelEnabled);
|
||||
|
||||
return newViewportInteractionModelEnabled;
|
||||
}
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -19,8 +19,6 @@ namespace AzToolsFramework
|
||||
{
|
||||
namespace ViewportInteraction
|
||||
{
|
||||
const AZ::s32 g_mainViewportEntityDebugDisplayId = AZ_CRC("MainViewportEntityDebugDisplayId", 0x58ae7fe8);
|
||||
|
||||
void ViewportInteractionReflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
|
||||
@@ -256,9 +256,5 @@ namespace AzToolsFramework
|
||||
|
||||
/// Reflect all viewport related types.
|
||||
void ViewportInteractionReflect(AZ::ReflectContext* context);
|
||||
|
||||
/// The Id the main DebugDisplayRequestBus will be connected on.
|
||||
extern const AZ::s32 g_mainViewportEntityDebugDisplayId;
|
||||
|
||||
} // namespace ViewportInteraction
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+11
-20
@@ -30,15 +30,9 @@ namespace AzToolsFramework
|
||||
ActionOverrideRequestBus::Handler::BusConnect(GetEntityContextId());
|
||||
ComponentModeFramework::ComponentModeSystemRequestBus::Handler::BusConnect();
|
||||
|
||||
// only create EditorTransformComponentSelection if we are using the new viewport interaction model
|
||||
// note: EditorDefaultSelection is still used when the new viewport interaction model is disabled to support
|
||||
// Component Mode when using legacy viewport interaction model
|
||||
if (IsNewViewportInteractionModelEnabled())
|
||||
{
|
||||
m_manipulatorManager =
|
||||
AZStd::make_shared<AzToolsFramework::ManipulatorManager>(AzToolsFramework::g_mainManipulatorManagerId);
|
||||
m_transformComponentSelection = AZStd::make_unique<EditorTransformComponentSelection>(entityDataCache);
|
||||
}
|
||||
m_manipulatorManager =
|
||||
AZStd::make_shared<AzToolsFramework::ManipulatorManager>(AzToolsFramework::g_mainManipulatorManagerId);
|
||||
m_transformComponentSelection = AZStd::make_unique<EditorTransformComponentSelection>(entityDataCache);
|
||||
}
|
||||
|
||||
EditorDefaultSelection::~EditorDefaultSelection()
|
||||
@@ -325,17 +319,14 @@ namespace AzToolsFramework
|
||||
m_transformComponentSelection->DisplayViewportSelection(viewportInfo, debugDisplay);
|
||||
}
|
||||
|
||||
if (IsNewViewportInteractionModelEnabled())
|
||||
{
|
||||
// poll and set the keyboard modifiers to ensure the mouse interaction is up to date
|
||||
m_currentInteraction.m_keyboardModifiers =
|
||||
AzToolsFramework::ViewportInteraction::BuildKeyboardModifiers(QGuiApplication::queryKeyboardModifiers());
|
||||
// draw the manipulators
|
||||
const AzFramework::CameraState cameraState = GetCameraState(viewportInfo.m_viewportId);
|
||||
debugDisplay.DepthTestOff();
|
||||
m_manipulatorManager->DrawManipulators(debugDisplay, cameraState, m_currentInteraction);
|
||||
debugDisplay.DepthTestOn();
|
||||
}
|
||||
// poll and set the keyboard modifiers to ensure the mouse interaction is up to date
|
||||
m_currentInteraction.m_keyboardModifiers =
|
||||
AzToolsFramework::ViewportInteraction::BuildKeyboardModifiers(QGuiApplication::queryKeyboardModifiers());
|
||||
// draw the manipulators
|
||||
const AzFramework::CameraState cameraState = GetCameraState(viewportInfo.m_viewportId);
|
||||
debugDisplay.DepthTestOff();
|
||||
m_manipulatorManager->DrawManipulators(debugDisplay, cameraState, m_currentInteraction);
|
||||
debugDisplay.DepthTestOn();
|
||||
}
|
||||
|
||||
void EditorDefaultSelection::DisplayViewportSelection2d(
|
||||
|
||||
+9
-9
@@ -68,6 +68,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
const AZ::Entity* entity = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->FindEntity(entityId);
|
||||
AzFramework::EntityDebugDisplayEventBus::Event(
|
||||
entityId, &AzFramework::EntityDebugDisplayEvents::DisplayEntityViewport,
|
||||
viewportInfo, debugDisplay);
|
||||
@@ -84,10 +85,9 @@ namespace AzToolsFramework
|
||||
|
||||
if (ed_visibility_showAggregateEntityTransformedLocalBounds)
|
||||
{
|
||||
AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM);
|
||||
AZ::Transform worldFromLocal = entity->GetTransform()->GetWorldTM();
|
||||
|
||||
if (const AZ::Aabb localAabb = AzFramework::CalculateEntityLocalBoundsUnion(entityId); localAabb.IsValid())
|
||||
if (const AZ::Aabb localAabb = AzFramework::CalculateEntityLocalBoundsUnion(entity); localAabb.IsValid())
|
||||
{
|
||||
const AZ::Aabb worldAabb = localAabb.GetTransformedAabb(worldFromLocal);
|
||||
debugDisplay.SetColor(AZ::Colors::Turquoise);
|
||||
@@ -97,7 +97,7 @@ namespace AzToolsFramework
|
||||
|
||||
if (ed_visibility_showAggregateEntityWorldBounds)
|
||||
{
|
||||
if (const AZ::Aabb worldAabb = AzFramework::CalculateEntityWorldBoundsUnion(entityId); worldAabb.IsValid())
|
||||
if (const AZ::Aabb worldAabb = AzFramework::CalculateEntityWorldBoundsUnion(entity); worldAabb.IsValid())
|
||||
{
|
||||
debugDisplay.SetColor(AZ::Colors::Magenta);
|
||||
debugDisplay.DrawWireBox(worldAabb.GetMin(), worldAabb.GetMax());
|
||||
@@ -141,16 +141,16 @@ namespace AzToolsFramework
|
||||
const AZ::Vector3& entityPosition = m_entityDataCache->GetVisibleEntityPosition(entityCacheIndex);
|
||||
|
||||
// selecting based on 2d icon - should only do it when visible and not selected
|
||||
const QPoint screenPosition = GetScreenPosition(viewportId, entityPosition);
|
||||
const AzFramework::ScreenPoint screenPosition = GetScreenPosition(viewportId, entityPosition);
|
||||
|
||||
const float distSqFromCamera = cameraState.m_position.GetDistanceSq(entityPosition);
|
||||
const auto iconRange = static_cast<float>(GetIconScale(distSqFromCamera) * s_iconSize * 0.5f);
|
||||
const auto screenCoords = mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates;
|
||||
|
||||
if ( screenCoords.m_x >= screenPosition.x() - iconRange
|
||||
&& screenCoords.m_x <= screenPosition.x() + iconRange
|
||||
&& screenCoords.m_y >= screenPosition.y() - iconRange
|
||||
&& screenCoords.m_y <= screenPosition.y() + iconRange)
|
||||
if ( screenCoords.m_x >= screenPosition.m_x - iconRange
|
||||
&& screenCoords.m_x <= screenPosition.m_x + iconRange
|
||||
&& screenCoords.m_y >= screenPosition.m_y - iconRange
|
||||
&& screenCoords.m_y <= screenPosition.m_y + iconRange)
|
||||
{
|
||||
entityIdUnderCursor = entityId;
|
||||
break;
|
||||
|
||||
+6
-3
@@ -13,7 +13,9 @@
|
||||
#include "EditorSelectionUtil.h"
|
||||
|
||||
#include <AzCore/Math/Aabb.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Math/IntersectSegment.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzFramework/Visibility/BoundsBus.h>
|
||||
#include <AzToolsFramework/API/ComponentEntitySelectionBus.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
@@ -28,7 +30,8 @@ namespace AzToolsFramework
|
||||
{
|
||||
if (Centered(pivot))
|
||||
{
|
||||
if (const AZ::Aabb localBound = AzFramework::CalculateEntityLocalBoundsUnion(entityId);
|
||||
const AZ::Entity* entity = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->FindEntity(entityId);
|
||||
if (const AZ::Aabb localBound = AzFramework::CalculateEntityLocalBoundsUnion(entity);
|
||||
localBound.IsValid())
|
||||
{
|
||||
return localBound.GetCenter();
|
||||
@@ -53,11 +56,11 @@ namespace AzToolsFramework
|
||||
return AZ::GetMax(projectedCameraDistance, cameraState.m_nearClip) / apparentDistance;
|
||||
}
|
||||
|
||||
QPoint GetScreenPosition(const int viewportId, const AZ::Vector3& worldTranslation)
|
||||
AzFramework::ScreenPoint GetScreenPosition(const int viewportId, const AZ::Vector3& worldTranslation)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
QPoint screenPosition = QPoint();
|
||||
auto screenPosition = AzFramework::ScreenPoint(0, 0);
|
||||
ViewportInteraction::ViewportInteractionRequestBus::EventResult(
|
||||
screenPosition, viewportId,
|
||||
&ViewportInteraction::ViewportInteractionRequestBus::Events::ViewportWorldToScreen,
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ namespace AzToolsFramework
|
||||
const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState);
|
||||
|
||||
/// Map from world space to screen space.
|
||||
QPoint GetScreenPosition(int viewportId, const AZ::Vector3& worldTranslation);
|
||||
AzFramework::ScreenPoint GetScreenPosition(int viewportId, const AZ::Vector3& worldTranslation);
|
||||
|
||||
/// Given a mouse interaction, determine if the pick ray from its position
|
||||
/// in screen space intersected an aabb in world space.
|
||||
|
||||
+4
-4
@@ -316,14 +316,14 @@ namespace AzToolsFramework
|
||||
|
||||
template<typename EntitySelectFuncType, typename EntityIdContainer, typename Compare>
|
||||
static void BoxSelectAddRemoveToEntitySelection(
|
||||
const AZStd::optional<QRect>& boxSelect, const QPoint& screenPosition, const AZ::EntityId visibleEntityId,
|
||||
const AZStd::optional<QRect>& boxSelect, const AzFramework::ScreenPoint& screenPosition, const AZ::EntityId visibleEntityId,
|
||||
const EntityIdContainer& incomingEntityIds, EntityIdContainer& outgoingEntityIds,
|
||||
EditorTransformComponentSelection& entityTransformComponentSelection,
|
||||
EntitySelectFuncType selectFunc1, EntitySelectFuncType selectFunc2, Compare outgoingCheck)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
if (boxSelect->contains(screenPosition))
|
||||
if (boxSelect->contains(ViewportInteraction::QPointFromScreenPoint(screenPosition)))
|
||||
{
|
||||
const auto entityIt = incomingEntityIds.find(visibleEntityId);
|
||||
|
||||
@@ -389,7 +389,7 @@ namespace AzToolsFramework
|
||||
const AZ::EntityId entityId = entityDataCache.GetVisibleEntityId(entityCacheIndex);
|
||||
const AZ::Vector3& entityPosition = entityDataCache.GetVisibleEntityPosition(entityCacheIndex);
|
||||
|
||||
const QPoint screenPosition = GetScreenPosition(viewportId, entityPosition);
|
||||
const AzFramework::ScreenPoint screenPosition = GetScreenPosition(viewportId, entityPosition);
|
||||
|
||||
if (currentKeyboardModifiers.Ctrl())
|
||||
{
|
||||
@@ -927,7 +927,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
|
||||
worldSurfacePosition, viewportId,
|
||||
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
|
||||
ViewportInteraction::QPointFromScreenPoint(mouseInteraction.m_mousePick.m_screenCoordinates));
|
||||
mouseInteraction.m_mousePick.m_screenCoordinates);
|
||||
|
||||
// convert to local space - snap if enabled
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId);
|
||||
|
||||
@@ -70,11 +70,6 @@ set(FILES
|
||||
AssetCatalog/PlatformAddressedAssetCatalog.cpp
|
||||
AssetCatalog/PlatformAddressedAssetCatalogManager.h
|
||||
AssetCatalog/PlatformAddressedAssetCatalogManager.cpp
|
||||
MaterialBrowser/MaterialBrowserBus.h
|
||||
MaterialBrowser/MaterialBrowserComponent.cpp
|
||||
MaterialBrowser/MaterialBrowserComponent.h
|
||||
MaterialBrowser/MaterialThumbnail.cpp
|
||||
MaterialBrowser/MaterialThumbnail.h
|
||||
Thumbnails/ThumbnailerComponent.cpp
|
||||
Thumbnails/ThumbnailerComponent.h
|
||||
Thumbnails/LoadingThumbnail.cpp
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ namespace Benchmark
|
||||
}
|
||||
BENCHMARK_REGISTER_F(BM_PrefabUpdateInstances, UpdateInstances_SingeEntityInstances)
|
||||
->RangeMultiplier(10)
|
||||
->Range(100, 1000)
|
||||
->Range(100, 10000)
|
||||
->Unit(benchmark::kMillisecond)
|
||||
->Complexity();
|
||||
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
#include <AzToolsFramework/Application/ToolsApplication.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
|
||||
#include <AzToolsFramework/ToolsComponents/ScriptEditorComponent.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx>
|
||||
#include <AzToolsFramework/API/EntityPropertyEditorRequestsBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorLockComponent.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorVisibilityComponent.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorDefaultSelection.h>
|
||||
|
||||
#include <AzCore/IO/Streamer/StreamerComponent.h>
|
||||
#include <AzCore/Asset/AssetManagerComponent.h>
|
||||
#include <AzCore/std/sort.h>
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace UnitTest
|
||||
|
||||
TEST(EntityPropertyEditorTests, PrioritySort_NonTransformAsFirstItem_TransformMovesToTopRemainderUnchanged)
|
||||
{
|
||||
ComponentApplication app;
|
||||
ToolsApplication app;
|
||||
|
||||
AZ::Entity::ComponentArrayType unorderedComponents;
|
||||
AZ::Entity::ComponentArrayType orderedComponents;
|
||||
@@ -68,12 +68,18 @@ namespace UnitTest
|
||||
|
||||
Entity* systemEntity = app.Create(desc, startupParams);
|
||||
|
||||
// Need to reflect the components so that edit attribute used for sorting, such as FixedComponentListIndex, get set.
|
||||
app.RegisterComponentDescriptor(AzToolsFramework::Components::TransformComponent::CreateDescriptor());
|
||||
app.RegisterComponentDescriptor(AzToolsFramework::Components::ScriptEditorComponent::CreateDescriptor());
|
||||
app.RegisterComponentDescriptor(AZ::AssetManagerComponent::CreateDescriptor());
|
||||
|
||||
// Add more than 31 components, as we are testing the case where the sort fails when there are 32 or more items.
|
||||
const int numFillerItems = 32;
|
||||
|
||||
for (int commentIndex = 0; commentIndex < numFillerItems; commentIndex++)
|
||||
{
|
||||
unorderedComponents.insert(unorderedComponents.begin(), systemEntity->CreateComponent(AZ::StreamerComponent::RTTI_Type()));
|
||||
unorderedComponents.insert(unorderedComponents.begin(), systemEntity->CreateComponent(
|
||||
AzToolsFramework::Components::ScriptEditorComponent::RTTI_Type()));
|
||||
}
|
||||
|
||||
// Add a TransformComponent at the end which should be sorted to the beginning by the priority sort.
|
||||
|
||||
@@ -211,6 +211,15 @@ namespace UnitTest
|
||||
EXPECT_EQ(screenPoint, ScreenPoint(45, 170));
|
||||
}
|
||||
|
||||
TEST(ViewportScreen, ScreenVectorLengthReturned)
|
||||
{
|
||||
using AzFramework::ScreenVector;
|
||||
|
||||
EXPECT_NEAR(AzFramework::ScreenVectorLength(ScreenVector(1, 1)), 1.41421f, 0.001f);
|
||||
EXPECT_NEAR(AzFramework::ScreenVectorLength(ScreenVector(3, 4)), 5.0f, 0.001f);
|
||||
EXPECT_NEAR(AzFramework::ScreenVectorLength(ScreenVector(12, 15)), 19.20937f, 0.001f);
|
||||
}
|
||||
|
||||
TEST(ViewportScreen, CanGetCameraTransformFromCameraViewAndBack)
|
||||
{
|
||||
const auto screenDimensions = AZ::Vector2(1024.0f, 768.0f);
|
||||
|
||||
@@ -62,8 +62,8 @@ namespace UnitTest
|
||||
SetupRowOfEntities(AZ::Vector3::CreateAxisX(-20.0f), AZ::Vector3::CreateAxisX(2.0f));
|
||||
|
||||
// request the entity union bounds system to update
|
||||
AzFramework::EntityBoundsUnionRequestBus::Broadcast(
|
||||
&AzFramework::EntityBoundsUnionRequestBus::Events::ProcessEntityBoundsUnionRequests);
|
||||
AzFramework::IEntityBoundsUnionRequestBus::Broadcast(
|
||||
&AzFramework::IEntityBoundsUnionRequestBus::Events::ProcessEntityBoundsUnionRequests);
|
||||
|
||||
// create default camera looking down the negative y-axis moved just back from the origin
|
||||
AzFramework::CameraState cameraState = AzFramework::CreateDefaultCamera(
|
||||
@@ -101,8 +101,8 @@ namespace UnitTest
|
||||
SetupRowOfEntities(AZ::Vector3::CreateAxisX(-20.0f), AZ::Vector3::CreateAxisX(2.0f));
|
||||
|
||||
// request the entity union bounds system to update
|
||||
AzFramework::EntityBoundsUnionRequestBus::Broadcast(
|
||||
&AzFramework::EntityBoundsUnionRequestBus::Events::ProcessEntityBoundsUnionRequests);
|
||||
AzFramework::IEntityBoundsUnionRequestBus::Broadcast(
|
||||
&AzFramework::IEntityBoundsUnionRequestBus::Events::ProcessEntityBoundsUnionRequests);
|
||||
|
||||
// create default camera looking down the negative x-axis moved along the x-axis and tilted slightly down
|
||||
AzFramework::CameraState cameraState = AzFramework::CreateDefaultCamera(
|
||||
@@ -143,15 +143,15 @@ namespace UnitTest
|
||||
SetupRowOfEntities(AZ::Vector3::CreateAxisX(-20.0f), AZ::Vector3::CreateAxisX(2.0f));
|
||||
|
||||
// request the entity union bounds system to update
|
||||
AzFramework::EntityBoundsUnionRequestBus::Broadcast(
|
||||
&AzFramework::EntityBoundsUnionRequestBus::Events::ProcessEntityBoundsUnionRequests);
|
||||
AzFramework::IEntityBoundsUnionRequestBus::Broadcast(
|
||||
&AzFramework::IEntityBoundsUnionRequestBus::Events::ProcessEntityBoundsUnionRequests);
|
||||
|
||||
const AZ::EntityId entityIdToMove = m_editorEntityIds[10];
|
||||
AZ::TransformBus::Event(
|
||||
entityIdToMove, &AZ::TransformBus::Events::SetWorldTranslation, AZ::Vector3::CreateAxisZ(100.0f));
|
||||
|
||||
AzFramework::EntityBoundsUnionRequestBus::Broadcast(
|
||||
&AzFramework::EntityBoundsUnionRequestBus::Events::ProcessEntityBoundsUnionRequests);
|
||||
AzFramework::IEntityBoundsUnionRequestBus::Broadcast(
|
||||
&AzFramework::IEntityBoundsUnionRequestBus::Events::ProcessEntityBoundsUnionRequests);
|
||||
|
||||
// create default camera looking down the negative y-axis moved just back from the origin
|
||||
AzFramework::CameraState cameraState = AzFramework::CreateDefaultCamera(
|
||||
@@ -241,8 +241,8 @@ namespace UnitTest
|
||||
{
|
||||
m_localAabb = localAabb;
|
||||
|
||||
AzFramework::EntityBoundsUnionRequestBus::Broadcast(
|
||||
&AzFramework::EntityBoundsUnionRequestBus::Events::RefreshEntityLocalBoundsUnion, GetEntityId());
|
||||
AzFramework::IEntityBoundsUnionRequestBus::Broadcast(
|
||||
&AzFramework::IEntityBoundsUnionRequestBus::Events::RefreshEntityLocalBoundsUnion, GetEntityId());
|
||||
}
|
||||
|
||||
TEST_F(EditorVisibilityFixture, UpdatedBoundsIntersectingFrustumAddsVisibleEntity)
|
||||
@@ -264,8 +264,8 @@ namespace UnitTest
|
||||
entityId, &AZ::TransformBus::Events::SetWorldTranslation, AZ::Vector3(40.0f, -3.0f, 20.0f));
|
||||
|
||||
// request the entity union bounds system to update
|
||||
AzFramework::EntityBoundsUnionRequestBus::Broadcast(
|
||||
&AzFramework::EntityBoundsUnionRequestBus::Events::ProcessEntityBoundsUnionRequests);
|
||||
AzFramework::IEntityBoundsUnionRequestBus::Broadcast(
|
||||
&AzFramework::IEntityBoundsUnionRequestBus::Events::ProcessEntityBoundsUnionRequests);
|
||||
|
||||
// create default camera looking down the positive x-axis moved to position offset from world origin
|
||||
AzFramework::CameraState cameraState = AzFramework::CreateDefaultCamera(
|
||||
@@ -288,8 +288,8 @@ namespace UnitTest
|
||||
testBoundComponent->ChangeBounds(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-2.5f), AZ::Vector3(2.5f)));
|
||||
|
||||
// perform an 'update' of the visibility system
|
||||
AzFramework::EntityBoundsUnionRequestBus::Broadcast(
|
||||
&AzFramework::EntityBoundsUnionRequestBus::Events::ProcessEntityBoundsUnionRequests);
|
||||
AzFramework::IEntityBoundsUnionRequestBus::Broadcast(
|
||||
&AzFramework::IEntityBoundsUnionRequestBus::Events::ProcessEntityBoundsUnionRequests);
|
||||
|
||||
entityVisibilityQuery.UpdateVisibility(cameraState);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user