Merge branch 'stabilization/2110' into Prism/DeleteUpdateGemsUI

This commit is contained in:
nggieber
2021-11-11 11:52:49 -08:00
96 changed files with 968 additions and 890 deletions
-10
View File
@@ -1362,16 +1362,6 @@ void CCryEditApp::CompileCriticalAssets() const
assetsInQueueNotifcation.BusDisconnect();
CCryEditApp::OutputStartupMessage(QString("Asset Processor is now ready."));
// VERY early on, as soon as we can, request that the asset system make sure the following assets take priority over others,
// so that by the time we ask for them there is a greater likelihood that they're already good to go.
// these can be loaded later but are still important:
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, "/texturemsg/");
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, "engineassets/materials");
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, "engineassets/geomcaches");
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, "engineassets/objects");
// some are specifically extra important and will cause issues if missing completely:
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::CompileAssetSync, "engineassets/objects/default.cgf");
}
bool CCryEditApp::ConnectToAssetProcessor() const
-1
View File
@@ -60,7 +60,6 @@ struct IFileUtil
EFILE_TYPE_GEOMETRY,
EFILE_TYPE_TEXTURE,
EFILE_TYPE_SOUND,
EFILE_TYPE_GEOMCACHE,
EFILE_TYPE_LAST,
};
+3 -15
View File
@@ -956,11 +956,7 @@ void CEntityObject::Serialize(CObjectArchive& ar)
QString attachmentType;
xmlNode->getAttr("AttachmentType", attachmentType);
if (attachmentType == "GeomCacheNode")
{
m_attachmentType = eAT_GeomCacheNode;
}
else if (attachmentType == "CharacterBone")
if (attachmentType == "CharacterBone")
{
m_attachmentType = eAT_CharacterBone;
}
@@ -987,11 +983,7 @@ void CEntityObject::Serialize(CObjectArchive& ar)
{
if (m_attachmentType != eAT_Pivot)
{
if (m_attachmentType == eAT_GeomCacheNode)
{
xmlNode->setAttr("AttachmentType", "GeomCacheNode");
}
else if (m_attachmentType == eAT_CharacterBone)
if (m_attachmentType == eAT_CharacterBone)
{
xmlNode->setAttr("AttachmentType", "CharacterBone");
}
@@ -1091,11 +1083,7 @@ XmlNodeRef CEntityObject::Export([[maybe_unused]] const QString& levelPath, XmlN
objNode->setAttr("ParentId", parentEntity->GetEntityId());
if (m_attachmentType != eAT_Pivot)
{
if (m_attachmentType == eAT_GeomCacheNode)
{
objNode->setAttr("AttachmentType", "GeomCacheNode");
}
else if (m_attachmentType == eAT_CharacterBone)
if (m_attachmentType == eAT_CharacterBone)
{
objNode->setAttr("AttachmentType", "CharacterBone");
}
-1
View File
@@ -131,7 +131,6 @@ public:
enum EAttachmentType
{
eAT_Pivot,
eAT_GeomCacheNode,
eAT_CharacterBone,
};
+1 -1
View File
@@ -608,7 +608,7 @@ bool CObjectManager::AddObject(CBaseObject* obj)
if (CEntityObject* entityObj = qobject_cast<CEntityObject*>(obj))
{
CEntityObject::EAttachmentType attachType = entityObj->GetAttachType();
if (attachType == CEntityObject::EAttachmentType::eAT_GeomCacheNode || attachType == CEntityObject::EAttachmentType::eAT_CharacterBone)
if (attachType == CEntityObject::EAttachmentType::eAT_CharacterBone)
{
m_animatedAttachedEntities.insert(entityObj);
}
@@ -13,6 +13,7 @@
#include <Atom/RPI.Public/Scene.h>
#include <Atom/RPI.Public/View.h>
#include <Atom/RPI.Reflect/System/RenderPipelineDescriptor.h>
#include <PostProcess/PostProcessFeatureProcessor.h>
#include <AzCore/Component/TransformBus.h>
#include <AzCore/Math/MatrixUtils.h>
#include <AzCore/Name/Name.h>
@@ -47,18 +48,42 @@ namespace TrackView
AZ::Name viewName = AZ::Name("MainCamera");
m_view = AZ::RPI::View::CreateView(viewName, AZ::RPI::View::UsageCamera);
m_renderPipeline->SetDefaultView(m_view);
m_targetView = scene.GetDefaultRenderPipeline()->GetDefaultView();
if (AZ::Render::PostProcessFeatureProcessor* fp = scene.GetFeatureProcessor<AZ::Render::PostProcessFeatureProcessor>())
{
// This will be set again to mimic the active camera in UpdateView
fp->SetViewAlias(m_view, m_targetView);
}
}
void AtomOutputFrameCapture::DestroyPipeline(AZ::RPI::Scene& scene)
{
if (AZ::Render::PostProcessFeatureProcessor* fp = scene.GetFeatureProcessor<AZ::Render::PostProcessFeatureProcessor>())
{
// Remove view alias introduced in CreatePipeline and UpdateView
fp->RemoveViewAlias(m_view);
}
scene.RemoveRenderPipeline(m_renderPipeline->GetId());
m_passHierarchy.clear();
m_renderPipeline.reset();
m_view.reset();
m_targetView.reset();
}
void AtomOutputFrameCapture::UpdateView(const AZ::Matrix3x4& cameraTransform, const AZ::Matrix4x4& cameraProjection)
void AtomOutputFrameCapture::UpdateView(const AZ::Matrix3x4& cameraTransform, const AZ::Matrix4x4& cameraProjection, const AZ::RPI::ViewPtr targetView)
{
if (targetView && targetView != m_targetView)
{
if (AZ::RPI::Scene* scene = SceneFromGameEntityContext())
{
if (AZ::Render::PostProcessFeatureProcessor* fp = scene->GetFeatureProcessor<AZ::Render::PostProcessFeatureProcessor>())
{
fp->SetViewAlias(m_view, targetView);
m_targetView = targetView;
}
}
}
m_view->SetCameraTransform(cameraTransform);
m_view->SetViewToClipMatrix(cameraProjection);
}
@@ -39,11 +39,12 @@ namespace TrackView
CaptureFinishedCallback captureFinishedCallback);
//! Update the internal view that is associated with the created pipeline.
void UpdateView(const AZ::Matrix3x4& cameraTransform, const AZ::Matrix4x4& cameraProjection);
void UpdateView(const AZ::Matrix3x4& cameraTransform, const AZ::Matrix4x4& cameraProjection, const AZ::RPI::ViewPtr targetView = nullptr);
private:
AZ::RPI::RenderPipelinePtr m_renderPipeline; //!< The internal render pipeline.
AZ::RPI::ViewPtr m_view; //!< The view associated with the render pipeline.
AZ::RPI::ViewPtr m_targetView; //!< The view that this render pipeline will mimic.
AZStd::vector<AZStd::string> m_passHierarchy; //!< Pass hierarchy (includes pipelineName and CopyToSwapChain).
CaptureFinishedCallback m_captureFinishedCallback; //!< Stored callback called from OnCaptureFinished.
@@ -16,6 +16,7 @@
#include <AzCore/Component/ComponentApplication.h>
#include <AzFramework/Windowing/WindowBus.h>
#include <Atom/RPI.Public/ViewProviderBus.h>
// Qt
#include <QAction>
@@ -91,9 +92,12 @@ namespace
static void UpdateAtomOutputFrameCaptureView(TrackView::AtomOutputFrameCapture& atomOutputFrameCapture, const int width, const int height)
{
const AZ::EntityId activeCameraEntityId = TrackView::ActiveCameraEntityId();
AZ::RPI::ViewPtr view = nullptr;
AZ::RPI::ViewProviderBus::EventResult(view, activeCameraEntityId, &AZ::RPI::ViewProvider::GetView);
atomOutputFrameCapture.UpdateView(
TrackView::TransformFromEntityId(activeCameraEntityId),
TrackView::ProjectionFromCameraEntityId(activeCameraEntityId, static_cast<float>(width), static_cast<float>(height)));
TrackView::ProjectionFromCameraEntityId(activeCameraEntityId, aznumeric_cast<float>(width), aznumeric_cast<float>(height)),
view);
}
CSequenceBatchRenderDialog::CSequenceBatchRenderDialog(float fps, QWidget* pParent /* = nullptr */)
+2 -2
View File
@@ -54,8 +54,8 @@
#include <Shellapi.h>
#endif
bool CFileUtil::s_singleFileDlgPref[IFileUtil::EFILE_TYPE_LAST] = { true, true, true, true, true };
bool CFileUtil::s_multiFileDlgPref[IFileUtil::EFILE_TYPE_LAST] = { true, true, true, true, true };
bool CFileUtil::s_singleFileDlgPref[IFileUtil::EFILE_TYPE_LAST] = { true, true, true, true };
bool CFileUtil::s_multiFileDlgPref[IFileUtil::EFILE_TYPE_LAST] = { true, true, true, true };
CAutoRestorePrimaryCDRoot::~CAutoRestorePrimaryCDRoot()
{
+1 -1
View File
@@ -100,7 +100,7 @@ namespace AZ
void Set(float x, float y, float z);
//! Sets components from an array of 3 floats in xyz order.
void Set(float values[]);
void Set(const float values[]);
//! Indexed access using operator(), just for convenience.
float operator()(int32_t index) const;
@@ -186,7 +186,7 @@ namespace AZ
}
AZ_MATH_INLINE void Vector3::Set(float values[])
AZ_MATH_INLINE void Vector3::Set(const float values[])
{
m_value = Simd::Vec3::LoadImmediate(values[0], values[1], values[2]);
}
@@ -50,7 +50,12 @@ namespace AZ
if (!s_instance)
{
s_instance = Environment::FindVariable<NameDictionary>(NameDictionaryInstanceName);
// Because the NameDictionary allocates memory using the AZ::Allocator and it is created
// in the executable memory space, it's ownership cannot be transferred to other module memory spaces
// Otherwise this could cause the the NameDictionary to be destroyed in static de-init
// after the AZ::Allocators have been destroyed
// Therefore we supply the isTransferOwnership value of false using CreateVariableEx
s_instance = AZ::Environment::CreateVariableEx<NameDictionary>(NameDictionaryInstanceName, true, false);
}
return s_instance.IsConstructed();
@@ -175,20 +175,14 @@ namespace AzToolsFramework::Prefab
m_focusedInstance = focusedInstance;
m_focusedTemplateId = focusedInstance->get().GetTemplateId();
AZ::EntityId containerEntityId;
if (focusedInstance->get().GetParentInstance() != AZStd::nullopt)
{
containerEntityId = focusedInstance->get().GetContainerEntityId();
}
else
{
containerEntityId = AZ::EntityId();
}
// Focus on the descendants of the container entity in the Editor, if the interface is initialized.
if (m_focusModeInterface)
{
const AZ::EntityId containerEntityId =
(focusedInstance->get().GetParentInstance() != AZStd::nullopt)
? focusedInstance->get().GetContainerEntityId()
: AZ::EntityId();
m_focusModeInterface->SetFocusRoot(containerEntityId);
}
@@ -45,6 +45,7 @@ AZ_POP_DISABLE_WARNING
#include <AzToolsFramework/AssetBrowser/EBusFindAssetTypeByName.h>
#include <AzToolsFramework/ComponentMode/ComponentModeDelegate.h>
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <AzToolsFramework/Slice/SliceDataFlagsCommand.h>
#include <AzToolsFramework/Slice/SliceMetadataEntityContextBus.h>
@@ -894,25 +895,51 @@ namespace AzToolsFramework
{
if (!m_prefabsAreEnabled)
{
return m_isLevelEntityEditor ? InspectorLayout::LEVEL : InspectorLayout::ENTITY;
return m_isLevelEntityEditor ? InspectorLayout::Level : InspectorLayout::Entity;
}
// Prefabs layout logic
// If this is the container entity for the root instance, treat it like a level entity.
AZ::EntityId levelContainerEntityId = m_prefabPublicInterface->GetLevelInstanceContainerEntityId();
if (AZStd::find(m_selectedEntityIds.begin(), m_selectedEntityIds.end(), levelContainerEntityId) != m_selectedEntityIds.end())
{
if (m_selectedEntityIds.size() > 1)
{
return InspectorLayout::INVALID;
return InspectorLayout::Invalid;
}
else
{
return InspectorLayout::LEVEL;
return InspectorLayout::Level;
}
}
else
{
return InspectorLayout::ENTITY;
// If this is the container entity for the currently focused prefab, utilize a separate layout.
if (auto prefabFocusPublicInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabFocusPublicInterface>::Get())
{
AzFramework::EntityContextId editorEntityContextId = AzFramework::EntityContextId::CreateNull();
EditorEntityContextRequestBus::BroadcastResult(
editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
AZ::EntityId focusedPrefabContainerEntityId =
prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId);
if (AZStd::find(m_selectedEntityIds.begin(), m_selectedEntityIds.end(), focusedPrefabContainerEntityId) !=
m_selectedEntityIds.end())
{
if (m_selectedEntityIds.size() > 1)
{
return InspectorLayout::Invalid;
}
else
{
return InspectorLayout::ContainerEntityOfFocusedPrefab;
}
}
}
}
return InspectorLayout::Entity;
}
void EntityPropertyEditor::UpdateEntityDisplay()
@@ -921,7 +948,7 @@ namespace AzToolsFramework
InspectorLayout layout = GetCurrentInspectorLayout();
if (layout == InspectorLayout::LEVEL)
if (!m_prefabsAreEnabled && layout == InspectorLayout::Level)
{
AZStd::string levelName;
AzToolsFramework::EditorRequestBus::BroadcastResult(levelName, &AzToolsFramework::EditorRequests::GetLevelName);
@@ -963,14 +990,19 @@ namespace AzToolsFramework
InspectorLayout layout = GetCurrentInspectorLayout();
if (layout == InspectorLayout::LEVEL)
if (layout == InspectorLayout::Level)
{
// The Level Inspector should only have a list of selectable components after the
// level entity itself is valid (i.e. "selected").
return selection.empty() ? SelectionEntityTypeInfo::None : SelectionEntityTypeInfo::LevelEntity;
}
if (layout == InspectorLayout::INVALID)
if (layout == InspectorLayout::ContainerEntityOfFocusedPrefab)
{
return selection.empty() ? SelectionEntityTypeInfo::None : SelectionEntityTypeInfo::ContainerEntityOfFocusedPrefab;
}
if (layout == InspectorLayout::Invalid)
{
return SelectionEntityTypeInfo::Mixed;
}
@@ -1140,7 +1172,8 @@ namespace AzToolsFramework
}
}
bool isLevelLayout = GetCurrentInspectorLayout() == InspectorLayout::LEVEL;
bool isLevelLayout = GetCurrentInspectorLayout() == InspectorLayout::Level;
bool isContainerOfFocusedPrefabLayout = GetCurrentInspectorLayout() == InspectorLayout::ContainerEntityOfFocusedPrefab;
m_gui->m_entityDetailsLabel->setText(entityDetailsLabelText);
m_gui->m_entityDetailsLabel->setVisible(entityDetailsVisible);
@@ -1148,10 +1181,14 @@ namespace AzToolsFramework
m_gui->m_entityNameLabel->setVisible(hasEntitiesDisplayed);
m_gui->m_entityIcon->setVisible(hasEntitiesDisplayed);
m_gui->m_pinButton->setVisible(m_overrideSelectedEntityIds.empty() && hasEntitiesDisplayed && !m_isSystemEntityEditor);
m_gui->m_statusLabel->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
m_gui->m_statusComboBox->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
m_gui->m_entityIdLabel->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
m_gui->m_entityIdText->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
m_gui->m_statusLabel->setVisible(
hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
m_gui->m_statusComboBox->setVisible(
hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
m_gui->m_entityIdLabel->setVisible(
hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
m_gui->m_entityIdText->setVisible(
hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
bool displayComponentSearchBox = hasEntitiesDisplayed;
if (hasEntitiesDisplayed)
@@ -1159,7 +1196,9 @@ namespace AzToolsFramework
// Build up components to display
SharedComponentArray sharedComponentArray;
BuildSharedComponentArray(sharedComponentArray,
!(selectionEntityTypeInfo == SelectionEntityTypeInfo::OnlyStandardEntities || selectionEntityTypeInfo == SelectionEntityTypeInfo::OnlyPrefabEntities));
!(selectionEntityTypeInfo == SelectionEntityTypeInfo::OnlyStandardEntities ||
selectionEntityTypeInfo == SelectionEntityTypeInfo::OnlyPrefabEntities) ||
selectionEntityTypeInfo == SelectionEntityTypeInfo::ContainerEntityOfFocusedPrefab);
if (sharedComponentArray.size() == 0)
{
@@ -1175,7 +1214,8 @@ namespace AzToolsFramework
UpdateEntityDisplay();
}
m_gui->m_darkBox->setVisible(displayComponentSearchBox && !m_isSystemEntityEditor && !isLevelLayout);
m_gui->m_darkBox->setVisible(
displayComponentSearchBox && !m_isSystemEntityEditor && !isLevelLayout && !isContainerOfFocusedPrefabLayout);
m_gui->m_entitySearchBox->setVisible(displayComponentSearchBox);
bool displayAddComponentMenu = CanAddComponentsToSelection(selectionEntityTypeInfo);
@@ -354,7 +354,8 @@ namespace AzToolsFramework
OnlyLayerEntities,
OnlyPrefabEntities,
Mixed,
LevelEntity
LevelEntity,
ContainerEntityOfFocusedPrefab
};
/**
* Returns what kinds of entities are in the current selection. This is used because mixed selection
@@ -364,7 +365,7 @@ namespace AzToolsFramework
SelectionEntityTypeInfo GetSelectionEntityTypeInfo(const EntityIdList& selection) const;
/**
* Returns true if a selection matching the passed in selection informatation allows components to be added.
* Returns true if a selection matching the passed in selection information allows components to be added.
*/
bool CanAddComponentsToSelection(const SelectionEntityTypeInfo& selectionEntityTypeInfo) const;
@@ -581,9 +582,10 @@ namespace AzToolsFramework
enum class InspectorLayout
{
ENTITY = 0, // All selected entities are regular entities
LEVEL, // The selected entity is the level prefab container entity
INVALID // Other entities are selected alongside the level prefab container entity
Entity = 0, // All selected entities are regular entities.
Level, // The selected entity is the prefab container entity for the level prefab, or the slice level entity.
ContainerEntityOfFocusedPrefab, // The selected entity is the prefab container entity for the focused prefab.
Invalid // Other entities are selected alongside the level prefab container entity.
};
InspectorLayout GetCurrentInspectorLayout() const;
@@ -28,6 +28,7 @@
#include <AzToolsFramework/Manipulators/TranslationManipulators.h>
#include <AzToolsFramework/Maths/TransformUtils.h>
#include <AzToolsFramework/Prefab/PrefabFocusInterface.h>
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
#include <AzToolsFramework/ToolsComponents/EditorLockComponentBus.h>
#include <AzToolsFramework/ToolsComponents/EditorVisibilityBus.h>
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
@@ -1177,8 +1178,10 @@ namespace AzToolsFramework
continue;
}
const AZ::Aabb bound = CalculateEditorEntitySelectionBounds(entityId, viewportInfo);
debugDisplay.DrawSolidBox(bound.GetMin(), bound.GetMax());
if (const AZ::Aabb bound = CalculateEditorEntitySelectionBounds(entityId, viewportInfo); bound.IsValid())
{
debugDisplay.DrawSolidBox(bound.GetMin(), bound.GetMax());
}
}
debugDisplay.DepthTestOn();
@@ -1334,39 +1337,6 @@ namespace AzToolsFramework
EndRecordManipulatorCommand();
});
// surface
translationManipulators->InstallSurfaceManipulatorMouseDownCallback(
[this, manipulatorEntityIds]([[maybe_unused]] const SurfaceManipulator::Action& action)
{
BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds->m_entityIds);
InitializeTranslationLookup(m_entityIdManipulators);
m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation();
m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform());
// [ref 1.]
BeginRecordManipulatorCommand();
});
translationManipulators->InstallSurfaceManipulatorMouseMoveCallback(
[this, prevModifiers, manipulatorEntityIds](const SurfaceManipulator::Action& action) mutable
{
UpdateTranslationManipulator(
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers,
m_transformChangedInternally, m_spaceCluster.m_spaceLock);
});
translationManipulators->InstallSurfaceManipulatorMouseUpCallback(
[this, manipulatorEntityIds]([[maybe_unused]] const SurfaceManipulator::Action& action)
{
AzToolsFramework::EditorTransformChangeNotificationBus::Broadcast(
&AzToolsFramework::EditorTransformChangeNotificationBus::Events::OnEntityTransformChanged,
manipulatorEntityIds->m_entityIds);
EndRecordManipulatorCommand();
});
// transfer ownership
m_entityIdManipulators.m_manipulators = AZStd::move(translationManipulators);
}
@@ -3604,6 +3574,16 @@ namespace AzToolsFramework
m_selectedEntityIds.clear();
m_selectedEntityIds.reserve(selectedEntityIds.size());
AZStd::copy(selectedEntityIds.begin(), selectedEntityIds.end(), AZStd::inserter(m_selectedEntityIds, m_selectedEntityIds.end()));
// Do not create manipulators for the container entity of the focused prefab.
if (auto prefabFocusPublicInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabFocusPublicInterface>::Get())
{
AzFramework::EntityContextId editorEntityContextId = GetEntityContextId();
if (AZ::EntityId focusRoot = prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId); focusRoot.IsValid())
{
m_selectedEntityIds.erase(focusRoot);
}
}
}
void EditorTransformComponentSelection::OnTransformChanged(
-19
View File
@@ -369,7 +369,6 @@ namespace O3DELauncher
}
}
void CompileCriticalAssets();
void CreateRemoteFileIO();
bool ConnectToAssetProcessor()
@@ -397,29 +396,11 @@ namespace O3DELauncher
{
AZ_TracePrintf("Launcher", "Connected to Asset Processor\n");
CreateRemoteFileIO();
CompileCriticalAssets();
}
return connectedToAssetProcessor;
}
//! Compiles the critical assets that are within the Engine directory of Open 3D Engine
//! This code should be in a centralized location, but doesn't belong in AzFramework
//! since it is specific to how Open 3D Engine projects has assets setup
void CompileCriticalAssets()
{
// VERY early on, as soon as we can, request that the asset system make sure the following assets take priority over others,
// so that by the time we ask for them there is a greater likelihood that they're already good to go.
// these can be loaded later but are still important:
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, "/texturemsg/");
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, "engineassets/materials");
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, "engineassets/geomcaches");
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, "engineassets/objects");
// some are specifically extra important and will cause issues if missing completely:
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::CompileAssetSync, "engineassets/objects/default.cgf");
}
//! Remote FileIO to use as a Virtual File System
//! Communication of FileIOBase operations occur through an AssetProcessor connection
void CreateRemoteFileIO()
@@ -61,8 +61,12 @@ namespace AssetBundler
{
AZStd::string absolutePath = filePath.toUtf8().data();
if (AZ::IO::FileIOBase::GetInstance()->Exists(absolutePath.c_str()))
{
AZStd::string projectName = pathToProjectNameMap.at(absolutePath);
{
AZStd::string projectName;
if (pathToProjectNameMap.contains(absolutePath))
{
projectName = pathToProjectNameMap.at(absolutePath);
}
// If a project name is already specified, then the associated file is a default file
LoadFile(absolutePath, projectName, !projectName.empty());
@@ -699,7 +699,6 @@ namespace AssetBuilderSDK
// XML files may contain generic data (avoid this in new builders - use a custom extension!)
static const char* xmlExtensions = ".xml";
static const char* geomCacheExtensions = ".cax";
static const char* skeletonExtensions = ".chr";
static AZ::Data::AssetType unknownAssetType = AZ::Data::AssetType::CreateNull();
@@ -710,7 +709,6 @@ namespace AssetBuilderSDK
static AZ::Data::AssetType textureMipsAssetType("{3918728C-D3CA-4D9E-813E-A5ED20C6821E}");
static AZ::Data::AssetType skinnedMeshLodsAssetType("{58E5824F-C27B-46FD-AD48-865BA41B7A51}");
static AZ::Data::AssetType staticMeshLodsAssetType("{9AAE4926-CB6A-4C60-9948-A1A22F51DB23}");
static AZ::Data::AssetType geomCacheAssetType("{EBC96071-E960-41B6-B3E3-328F515AE5DA}");
static AZ::Data::AssetType skeletonAssetType("{60161B46-21F0-4396-A4F0-F2CCF0664CDE}");
static AZ::Data::AssetType entityIconAssetType("{3436C30E-E2C5-4C3B-A7B9-66C94A28701B}");
@@ -822,11 +820,6 @@ namespace AssetBuilderSDK
return skinnedMeshAssetType;
}
if (AzFramework::StringFunc::Find(geomCacheExtensions, extension.c_str()) != AZStd::string::npos)
{
return geomCacheAssetType;
}
if (AzFramework::StringFunc::Find(skeletonExtensions, extension.c_str()) != AZStd::string::npos)
{
return skeletonAssetType;
@@ -41,5 +41,6 @@
<file>Download.svg</file>
<file>in_progress.gif</file>
<file>gem.svg</file>
<file>checkmark.svg</file>
</qresource>
</RCC>
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="15px" height="14px" viewBox="0 0 15 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Icons / Hub / Download Copy 5</title>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Screen-1-Copy-80" transform="translate(-425.000000, -251.000000)">
<g id="Icons-/-Hub-/-Download-Copy-5" transform="translate(424.573941, 250.098705)">
<rect id="Icon-Background" x="0" y="0" width="16" height="16"></rect>
<path d="M8,1.33333333 C11.6818983,1.33333333 14.6666667,4.31810167 14.6666667,8 C14.6666667,11.6818983 11.6818983,14.6666667 8,14.6666667 C4.31810167,14.6666667 1.33333333,11.6818983 1.33333333,8 C1.33333333,4.31810167 4.31810167,1.33333333 8,1.33333333 Z M12.0947571,4 L5.96649831,10.1282588 L3.60947571,7.77123617 L2.66666667,8.71404521 L5.96649831,12.0138769 L13.0375661,4.94280904 L12.0947571,4 Z" id="Combined-Shape" fill="#58BC61"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -18,7 +18,6 @@ namespace O3DE::ProjectManager
{
DownloadController::DownloadController(QWidget* parent)
: QObject()
, m_lastProgress(0)
, m_parent(parent)
{
m_worker = new DownloadWorker();
@@ -69,10 +68,9 @@ namespace O3DE::ProjectManager
}
}
void DownloadController::UpdateUIProgress(int progress)
void DownloadController::UpdateUIProgress(int bytesDownloaded, int totalBytes)
{
m_lastProgress = progress;
emit GemDownloadProgress(m_gemNames.front(), progress);
emit GemDownloadProgress(m_gemNames.front(), bytesDownloaded, totalBytes);
}
void DownloadController::HandleResults(const QString& result)
@@ -88,6 +86,7 @@ namespace O3DE::ProjectManager
QString gemName = m_gemNames.front();
m_gemNames.erase(m_gemNames.begin());
emit Done(gemName, succeeded);
emit GemDownloadRemoved(gemName);
if (!m_gemNames.empty())
{
@@ -53,7 +53,7 @@ namespace O3DE::ProjectManager
}
}
public slots:
void UpdateUIProgress(int progress);
void UpdateUIProgress(int bytesDownloaded, int totalBytes);
void HandleResults(const QString& result);
signals:
@@ -61,14 +61,12 @@ namespace O3DE::ProjectManager
void Done(const QString& gemName, bool success = true);
void GemDownloadAdded(const QString& gemName);
void GemDownloadRemoved(const QString& gemName);
void GemDownloadProgress(const QString& gemName, int percentage);
void GemDownloadProgress(const QString& gemName, int bytesDownloaded, int totalBytes);
private:
DownloadWorker* m_worker;
QThread m_workerThread;
QWidget* m_parent;
AZStd::vector<QString> m_gemNames;
int m_lastProgress;
};
} // namespace O3DE::ProjectManager
@@ -20,10 +20,9 @@ namespace O3DE::ProjectManager
void DownloadWorker::StartDownload()
{
auto gemDownloadProgress = [=](int downloadProgress)
auto gemDownloadProgress = [=](int bytesDownloaded, int totalBytes)
{
m_downloadProgress = downloadProgress;
emit UpdateProgress(downloadProgress);
emit UpdateProgress(bytesDownloaded, totalBytes);
};
AZ::Outcome<void, AZStd::string> gemInfoResult =
PythonBindingsInterface::Get()->DownloadGem(m_gemName, gemDownloadProgress, /*force*/true);
@@ -31,12 +31,11 @@ namespace O3DE::ProjectManager
void SetGemToDownload(const QString& gemName, bool downloadNow = true);
signals:
void UpdateProgress(int progress);
void UpdateProgress(int bytesDownloaded, int totalBytes);
void Done(QString result = "");
private:
QString m_gemName;
int m_downloadProgress;
};
} // namespace O3DE::ProjectManager
@@ -15,6 +15,8 @@
#include <QProgressBar>
#include <TagWidget.h>
#include <QMenu>
#include <QLocale>
#include <QMovie>
namespace O3DE::ProjectManager
{
@@ -224,7 +226,6 @@ namespace O3DE::ProjectManager
connect(m_downloadController, &DownloadController::GemDownloadAdded, this, &CartOverlayWidget::GemDownloadAdded);
connect(m_downloadController, &DownloadController::GemDownloadRemoved, this, &CartOverlayWidget::GemDownloadRemoved);
connect(m_downloadController, &DownloadController::GemDownloadProgress, this, &CartOverlayWidget::GemDownloadProgress);
connect(m_downloadController, &DownloadController::Done, this, &CartOverlayWidget::GemDownloadComplete);
}
void CartOverlayWidget::GemDownloadAdded(const QString& gemName)
@@ -288,29 +289,41 @@ namespace O3DE::ProjectManager
}
}
void CartOverlayWidget::GemDownloadProgress(const QString& gemName, int percentage)
void CartOverlayWidget::GemDownloadProgress(const QString& gemName, int bytesDownloaded, int totalBytes)
{
QWidget* gemToUpdate = m_downloadingListWidget->findChild<QWidget*>(gemName);
if (gemToUpdate)
{
QLabel* progressLabel = gemToUpdate->findChild<QLabel*>("DownloadProgressLabel");
if (progressLabel)
{
progressLabel->setText(QString("%1%").arg(percentage));
}
QProgressBar* progressBar = gemToUpdate->findChild<QProgressBar*>("DownloadProgressBar");
if (progressBar)
// totalBytes can be 0 if the server does not return a content-length for the object
if (totalBytes != 0)
{
progressBar->setValue(percentage);
int downloadPercentage = static_cast<int>((bytesDownloaded / static_cast<float>(totalBytes)) * 100);
if (progressLabel)
{
progressLabel->setText(QString("%1%").arg(downloadPercentage));
}
if (progressBar)
{
progressBar->setValue(downloadPercentage);
}
}
else
{
if (progressLabel)
{
progressLabel->setText(QLocale::system().formattedDataSize(bytesDownloaded));
}
if (progressBar)
{
progressBar->setRange(0, 0);
}
}
}
}
void CartOverlayWidget::GemDownloadComplete(const QString& gemName, bool /*success*/)
{
GemDownloadRemoved(gemName); // update the list to remove the gem that has finished
}
QVector<Tag> CartOverlayWidget::GetTagsFromModelIndices(const QVector<QModelIndex>& gems) const
{
QVector<Tag> tags;
@@ -389,7 +402,7 @@ namespace O3DE::ProjectManager
{
const QVector<QModelIndex> toBeAdded = m_gemModel->GatherGemsToBeAdded(/*includeDependencies=*/true);
const QVector<QModelIndex> toBeRemoved = m_gemModel->GatherGemsToBeRemoved(/*includeDependencies=*/true);
if (toBeAdded.isEmpty() && toBeRemoved.isEmpty())
if (toBeAdded.isEmpty() && toBeRemoved.isEmpty() && m_downloadController->IsDownloadQueueEmpty())
{
return;
}
@@ -430,6 +443,7 @@ namespace O3DE::ProjectManager
GemCatalogHeaderWidget::GemCatalogHeaderWidget(GemModel* gemModel, GemSortFilterProxyModel* filterProxyModel, DownloadController* downloadController, QWidget* parent)
: QFrame(parent)
, m_downloadController(downloadController)
{
QHBoxLayout* hLayout = new QHBoxLayout();
hLayout->setAlignment(Qt::AlignLeft);
@@ -456,8 +470,25 @@ namespace O3DE::ProjectManager
hLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding));
hLayout->addSpacerItem(new QSpacerItem(75, 0, QSizePolicy::Fixed));
CartButton* cartButton = new CartButton(gemModel, downloadController);
hLayout->addWidget(cartButton);
// spinner
m_downloadSpinnerMovie = new QMovie(":/in_progress.gif");
m_downloadSpinner = new QLabel(this);
m_downloadSpinner->setScaledContents(true);
m_downloadSpinner->setMaximumSize(16, 16);
m_downloadSpinner->setMovie(m_downloadSpinnerMovie);
hLayout->addWidget(m_downloadSpinner);
hLayout->addSpacing(8);
// downloading label
m_downloadLabel = new QLabel(tr("Downloading"));
hLayout->addWidget(m_downloadLabel);
m_downloadSpinner->hide();
m_downloadLabel->hide();
hLayout->addSpacing(16);
m_cartButton = new CartButton(gemModel, downloadController);
hLayout->addWidget(m_cartButton);
hLayout->addSpacing(16);
// Separating line
@@ -480,6 +511,27 @@ namespace O3DE::ProjectManager
gemMenuButton->setIcon(QIcon(":/menu.svg"));
gemMenuButton->setIconSize(QSize(36, 24));
hLayout->addWidget(gemMenuButton);
connect(m_downloadController, &DownloadController::GemDownloadAdded, this, &GemCatalogHeaderWidget::GemDownloadAdded);
connect(m_downloadController, &DownloadController::GemDownloadRemoved, this, &GemCatalogHeaderWidget::GemDownloadRemoved);
}
void GemCatalogHeaderWidget::GemDownloadAdded(const QString& /*gemName*/)
{
m_downloadSpinner->show();
m_downloadLabel->show();
m_downloadSpinnerMovie->start();
m_cartButton->ShowOverlay();
}
void GemCatalogHeaderWidget::GemDownloadRemoved(const QString& /*gemName*/)
{
if (m_downloadController->IsDownloadQueueEmpty())
{
m_downloadSpinner->hide();
m_downloadLabel->hide();
m_downloadSpinnerMovie->stop();
}
}
void GemCatalogHeaderWidget::ReinitForProject()
@@ -24,6 +24,7 @@ QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
QT_FORWARD_DECLARE_CLASS(QHBoxLayout)
QT_FORWARD_DECLARE_CLASS(QHideEvent)
QT_FORWARD_DECLARE_CLASS(QMoveEvent)
QT_FORWARD_DECLARE_CLASS(QMovie)
namespace O3DE::ProjectManager
{
@@ -39,8 +40,7 @@ namespace O3DE::ProjectManager
public slots:
void GemDownloadAdded(const QString& gemName);
void GemDownloadRemoved(const QString& gemName);
void GemDownloadProgress(const QString& gemName, int percentage);
void GemDownloadComplete(const QString& gemName, bool success);
void GemDownloadProgress(const QString& gemName, int bytesDownloaded, int totalBytes);
private:
QVector<Tag> GetTagsFromModelIndices(const QVector<QModelIndex>& gems) const;
@@ -96,6 +96,10 @@ namespace O3DE::ProjectManager
void ReinitForProject();
public slots:
void GemDownloadAdded(const QString& gemName);
void GemDownloadRemoved(const QString& gemName);
signals:
void AddGem();
void OpenGemsRepo();
@@ -104,5 +108,10 @@ namespace O3DE::ProjectManager
private:
AzQtComponents::SearchLineEdit* m_filterLineEdit = nullptr;
inline constexpr static int s_height = 60;
DownloadController* m_downloadController = nullptr;
QLabel* m_downloadSpinner = nullptr;
QLabel* m_downloadLabel = nullptr;
QMovie* m_downloadSpinnerMovie = nullptr;
CartButton* m_cartButton = nullptr;
};
} // namespace O3DE::ProjectManager
@@ -575,7 +575,7 @@ namespace O3DE::ProjectManager
QModelIndex index = m_gemModel->FindIndexByNameString(gemName);
if (index.isValid())
{
m_gemModel->setData(index, GemInfo::Downloaded, GemModel::RoleDownloadStatus);
m_proxyModel->setData(m_proxyModel->mapFromSource(index), GemInfo::DownloadSuccessful, GemModel::RoleDownloadStatus);
m_gemModel->setData(index, gemInfo.m_path, GemModel::RolePath);
m_gemModel->setData(index, gemInfo.m_path, GemModel::RoleDirectoryLink);
}
@@ -585,6 +585,14 @@ namespace O3DE::ProjectManager
}
}
}
else
{
QModelIndex index = m_gemModel->FindIndexByNameString(gemName);
if (index.isValid())
{
m_proxyModel->setData(m_proxyModel->mapFromSource(index), GemInfo::DownloadFailed, GemModel::RoleDownloadStatus);
}
}
}
ProjectManagerScreen GemCatalogScreen::GetScreenEnum()
@@ -57,6 +57,8 @@ namespace O3DE::ProjectManager
UnknownDownloadStatus = -1,
NotDownloaded,
Downloading,
DownloadSuccessful,
DownloadFailed,
Downloaded
};
static QString GetDownloadStatusString(DownloadStatus status);
@@ -37,6 +37,8 @@ namespace O3DE::ProjectManager
SetStatusIcon(m_notDownloadedPixmap, ":/Download.svg");
SetStatusIcon(m_unknownStatusPixmap, ":/X.svg");
SetStatusIcon(m_downloadSuccessfulPixmap, ":/checkmark.svg");
SetStatusIcon(m_downloadFailedPixmap, ":/Warning.svg");
m_downloadingMovie = new QMovie(":/in_progress.gif");
}
@@ -480,6 +482,14 @@ namespace O3DE::ProjectManager
currentFrame = currentFrame.scaled(s_statusIconSize, s_statusIconSize);
statusPixmap = &currentFrame;
}
else if (downloadStatus == GemInfo::DownloadStatus::DownloadSuccessful)
{
statusPixmap = &m_downloadSuccessfulPixmap;
}
else if (downloadStatus == GemInfo::DownloadStatus::DownloadFailed)
{
statusPixmap = &m_downloadFailedPixmap;
}
else if (downloadStatus == GemInfo::DownloadStatus::NotDownloaded)
{
statusPixmap = &m_notDownloadedPixmap;
@@ -97,6 +97,8 @@ namespace O3DE::ProjectManager
QPixmap m_unknownStatusPixmap;
QPixmap m_notDownloadedPixmap;
QPixmap m_downloadSuccessfulPixmap;
QPixmap m_downloadFailedPixmap;
QMovie* m_downloadingMovie = nullptr;
};
} // namespace O3DE::ProjectManager
@@ -1215,7 +1215,8 @@ namespace O3DE::ProjectManager
return AZ::Success(AZStd::move(gemInfos));
}
AZ::Outcome<void, AZStd::string> PythonBindings::DownloadGem(const QString& gemName, std::function<void(int)> gemProgressCallback, bool force)
AZ::Outcome<void, AZStd::string> PythonBindings::DownloadGem(
const QString& gemName, std::function<void(int, int)> gemProgressCallback, bool force)
{
// This process is currently limited to download a single gem at a time.
bool downloadSucceeded = false;
@@ -1230,9 +1231,9 @@ namespace O3DE::ProjectManager
false, // skip auto register
force, // force overwrite
pybind11::cpp_function(
[this, gemProgressCallback](int progress)
[this, gemProgressCallback](int bytesDownloaded, int totalBytes)
{
gemProgressCallback(progress);
gemProgressCallback(bytesDownloaded, totalBytes);
return m_requestCancelDownload;
}) // Callback for download progress and cancelling
@@ -66,7 +66,7 @@ namespace O3DE::ProjectManager
bool RemoveGemRepo(const QString& repoUri) override;
AZ::Outcome<QVector<GemRepoInfo>, AZStd::string> GetAllGemRepoInfos() override;
AZ::Outcome<QVector<GemInfo>, AZStd::string> GetAllGemRepoGemsInfos() override;
AZ::Outcome<void, AZStd::string> DownloadGem(const QString& gemName, std::function<void(int)> gemProgressCallback, bool force = false) override;
AZ::Outcome<void, AZStd::string> DownloadGem(const QString& gemName, std::function<void(int, int)> gemProgressCallback, bool force = false) override;
void CancelDownload() override;
bool IsGemUpdateAvaliable(const QString& gemName, const QString& lastUpdated) override;
@@ -231,7 +231,7 @@ namespace O3DE::ProjectManager
* @return an outcome with a string error message on failure.
*/
virtual AZ::Outcome<void, AZStd::string> DownloadGem(
const QString& gemName, std::function<void(int)> gemProgressCallback, bool force = false) = 0;
const QString& gemName, std::function<void(int, int)> gemProgressCallback, bool force = false) = 0;
/**
* Cancels the current download.