From 598c890cbc438ce0022625ac5edb14d0228ddd4e Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Tue, 29 Jun 2021 15:14:33 -0500 Subject: [PATCH 01/17] Fix nodes being incorrectly treated as bones Some nodes have aiBones created by AssImp even though they aren't bones. Filter these out by looking through the node graph and only considering Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> --- .../Importers/AssImpBoneImporter.cpp | 72 +++++++------------ .../Importers/AssImpTransformImporter.cpp | 29 +++++++- 2 files changed, 53 insertions(+), 48 deletions(-) diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp index 1828919c46..6ae228a8a8 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp @@ -40,59 +40,45 @@ namespace AZ } } - void EnumBonesInNode( - const aiScene* scene, const aiNode* node, AZStd::unordered_map& mainBoneList, - AZStd::unordered_map& boneLookup) + void MakeBoneMap(const aiScene* scene, AZStd::unordered_map& boneLookup) { - /* From AssImp Documentation - a) Create a map or a similar container to store which nodes are necessary for the skeleton. Pre-initialise it for all nodes with a "no". - b) For each bone in the mesh: - b1) Find the corresponding node in the scene's hierarchy by comparing their names. - b2) Mark this node as "yes" in the necessityMap. - b3) Mark all of its parents the same way until you 1) find the mesh's node or 2) the parent of the mesh's node. - c) Recursively iterate over the node hierarchy - c1) If the node is marked as necessary, copy it into the skeleton and check its children - c2) If the node is marked as not necessary, skip it and do not iterate over its children. - */ + AZStd::queue queue; + AZStd::unordered_set nodesWithNoMesh; - for (unsigned meshIndex = 0; meshIndex < node->mNumMeshes; ++meshIndex) + queue.push(scene->mRootNode); + + while (!queue.empty()) { - const aiMesh* mesh = scene->mMeshes[node->mMeshes[meshIndex]]; + const aiNode* currentNode = queue.front(); + queue.pop(); + + if (currentNode->mNumMeshes == 0) + { + nodesWithNoMesh.emplace(currentNode->mName.C_Str()); + } + + for (int childIndex = 0; childIndex < currentNode->mNumChildren; ++childIndex) + { + queue.push(currentNode->mChildren[childIndex]); + } + } + + for (unsigned meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) + { + const aiMesh* mesh = scene->mMeshes[meshIndex]; for (unsigned boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex) { const aiBone* bone = mesh->mBones[boneIndex]; - const aiNode* boneNode = scene->mRootNode->FindNode(bone->mName); - const aiNode* boneParent = boneNode->mParent; - - mainBoneList[bone->mName.C_Str()] = boneNode; - boneLookup[bone->mName.C_Str()] = bone; - - while (boneParent && boneParent != node && boneParent != node->mParent && boneParent != scene->mRootNode) + if (nodesWithNoMesh.contains(bone->mName.C_Str())) { - mainBoneList[boneParent->mName.C_Str()] = boneParent; - - boneParent = boneParent->mParent; + boneLookup.emplace(bone->mName.C_Str(), bone); } } } } - void EnumChildren( - const aiScene* scene, const aiNode* node, AZStd::unordered_map& mainBoneList, - AZStd::unordered_map& boneLookup) - { - EnumBonesInNode(scene, node, mainBoneList, boneLookup); - - for (unsigned childIndex = 0; childIndex < node->mNumChildren; ++childIndex) - { - const aiNode* child = node->mChildren[childIndex]; - - EnumChildren(scene, child, mainBoneList, boneLookup); - } - } - aiMatrix4x4 CalculateWorldTransform(const aiNode* currentNode) { aiMatrix4x4 transform = {}; @@ -122,14 +108,10 @@ namespace AZ bool isBone = false; { - AZStd::unordered_map mainBoneList; AZStd::unordered_map boneLookup; - EnumChildren(scene, scene->mRootNode, mainBoneList, boneLookup); + MakeBoneMap(scene, boneLookup); - if (mainBoneList.find(currentNode->mName.C_Str()) != mainBoneList.end()) - { - isBone = true; - } + isBone = boneLookup.contains(currentNode->mName.C_Str()); // If we have an animation, the bones will be listed in there if (!isBone) diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp index 5f9ffbd9b3..2f515c6174 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp @@ -42,9 +42,29 @@ namespace AZ } } - void GetAllBones( - const aiScene* scene, AZStd::unordered_multimap& boneLookup) + void GetAllBones(const aiScene* scene, AZStd::unordered_multimap& boneLookup) { + AZStd::queue queue; + AZStd::unordered_set nodesWithNoMesh; + + queue.push(scene->mRootNode); + + while (!queue.empty()) + { + const aiNode* currentNode = queue.front(); + queue.pop(); + + if (currentNode->mNumMeshes == 0) + { + nodesWithNoMesh.emplace(currentNode->mName.C_Str()); + } + + for (int childIndex = 0; childIndex < currentNode->mNumChildren; ++childIndex) + { + queue.push(currentNode->mChildren[childIndex]); + } + } + for (unsigned meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) { const aiMesh* mesh = scene->mMeshes[meshIndex]; @@ -53,7 +73,10 @@ namespace AZ { const aiBone* bone = mesh->mBones[boneIndex]; - boneLookup.emplace(bone->mName.C_Str(), bone); + if (nodesWithNoMesh.contains(bone->mName.C_Str())) + { + boneLookup.emplace(bone->mName.C_Str(), bone); + } } } } From df0fede8d295b08563e7201785c080847fffb316 Mon Sep 17 00:00:00 2001 From: hasareej Date: Wed, 9 Jun 2021 16:42:28 +0100 Subject: [PATCH 02/17] Hiding the 2 Clusters during Gameplay mode Signed-off-by: hultonha --- .../EditorTransformComponentSelection.cpp | 14 ++++++++++++++ .../EditorTransformComponentSelection.h | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp index 0dbaa42e1a..04af44ad79 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp @@ -1009,6 +1009,7 @@ namespace AzToolsFramework ToolsApplicationNotificationBus::Handler::BusConnect(); Camera::EditorCameraNotificationBus::Handler::BusConnect(); ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusConnect(entityContextId); + EditorEntityContextNotificationBus::Handler::BusConnect(); EditorEntityVisibilityNotificationBus::Router::BusRouterConnect(); EditorEntityLockComponentNotificationBus::Router::BusRouterConnect(); EditorManipulatorCommandUndoRedoRequestBus::Handler::BusConnect(entityContextId); @@ -1038,6 +1039,7 @@ namespace AzToolsFramework EditorEntityLockComponentNotificationBus::Router::BusRouterDisconnect(); EditorEntityVisibilityNotificationBus::Router::BusRouterDisconnect(); ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect(); + EditorEvents::Bus::Handler::BusDisconnect(); Camera::EditorCameraNotificationBus::Handler::BusDisconnect(); ToolsApplicationNotificationBus::Handler::BusDisconnect(); EditorTransformComponentSelectionRequestBus::Handler::BusDisconnect(); @@ -3625,6 +3627,18 @@ namespace AzToolsFramework ETCS::SetEntityLocalRotation(entityId, localRotation, m_transformChangedInternally); } + void EditorTransformComponentSelection::OnStartPlayInEditor() + { + SetViewportUiClusterVisible(m_transformModeClusterId, false); + SetViewportUiClusterVisible(m_spaceCluster.m_spaceClusterId, false); + } + + void EditorTransformComponentSelection::OnStopPlayInEditor() + { + SetViewportUiClusterVisible(m_transformModeClusterId, true); + SetViewportUiClusterVisible(m_spaceCluster.m_spaceClusterId, true); + } + namespace ETCS { // little raii wrapper to switch a value from true to false and back diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h index 2f1016cd6d..ccff1056ce 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h @@ -128,6 +128,7 @@ namespace AzToolsFramework , private ToolsApplicationNotificationBus::Handler , private Camera::EditorCameraNotificationBus::Handler , private ComponentModeFramework::EditorComponentModeNotificationBus::Handler + , private EditorEntityContextNotificationBus::Handler , private EditorEntityVisibilityNotificationBus::Router , private EditorEntityLockComponentNotificationBus::Router , private EditorManipulatorCommandUndoRedoRequestBus::Handler @@ -264,6 +265,10 @@ namespace AzToolsFramework void EnteredComponentMode(const AZStd::vector& componentModeTypes) override; void LeftComponentMode(const AZStd::vector& componentModeTypes) override; + // EditorEntityContextNotificationBus ... + void OnStartPlayInEditor() override; + void OnStopPlayInEditor() override; + // Helpers to safely interact with the TransformBus (requests). void SetEntityWorldTranslation(AZ::EntityId entityId, const AZ::Vector3& worldTranslation); void SetEntityLocalTranslation(AZ::EntityId entityId, const AZ::Vector3& localTranslation); From 32687cbcb23f0488187637e1f6951df6d8f03273 Mon Sep 17 00:00:00 2001 From: hasareej Date: Fri, 11 Jun 2021 12:18:03 +0100 Subject: [PATCH 03/17] PR feedback changes Signed-off-by: hultonha --- .../EditorTransformComponentSelection.cpp | 23 +++++++++++-------- .../EditorTransformComponentSelection.h | 5 +++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp index 04af44ad79..840a57d353 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp @@ -488,6 +488,13 @@ namespace AzToolsFramework return worldFromLocal.TransformPoint(CalculateCenterOffset(entityId, pivot)); } + void EditorTransformComponentSelection::SetAllViewportUiVisible(const bool visible) + { + SetViewportUiClusterVisible(m_transformModeClusterId, visible); + SetViewportUiClusterVisible(m_spaceCluster.m_spaceClusterId, visible); + m_viewportUiVisible = visible; + } + void EditorTransformComponentSelection::UpdateSpaceCluster(const ReferenceFrame referenceFrame) { auto buttonIdFromFrameFn = [this](const ReferenceFrame referenceFrame) @@ -1038,8 +1045,8 @@ namespace AzToolsFramework EditorManipulatorCommandUndoRedoRequestBus::Handler::BusDisconnect(); EditorEntityLockComponentNotificationBus::Router::BusRouterDisconnect(); EditorEntityVisibilityNotificationBus::Router::BusRouterDisconnect(); + EditorEntityContextNotificationBus::Handler::BusDisconnect(); ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect(); - EditorEvents::Bus::Handler::BusDisconnect(); Camera::EditorCameraNotificationBus::Handler::BusDisconnect(); ToolsApplicationNotificationBus::Handler::BusDisconnect(); EditorTransformComponentSelectionRequestBus::Handler::BusDisconnect(); @@ -2389,9 +2396,7 @@ namespace AzToolsFramework /*ID_VIEWPORTUI_VISIBLE=*/50040, "Toggle Viewport UI", "Hide/Show Viewport UI", [this]() { - SetViewportUiClusterVisible(m_transformModeClusterId, !m_viewportUiVisible); - SetViewportUiClusterVisible(m_spaceCluster.m_spaceClusterId, !m_viewportUiVisible); - m_viewportUiVisible = !m_viewportUiVisible; + SetAllViewportUiVisible(!m_viewportUiVisible); }); EditorMenuRequestBus::Broadcast(&EditorMenuRequests::RestoreEditMenuToDefault); @@ -3562,7 +3567,7 @@ namespace AzToolsFramework void EditorTransformComponentSelection::EnteredComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes) { - SetViewportUiClusterVisible(m_transformModeClusterId, false); + SetAllViewportUiVisible(false); EditorEntityLockComponentNotificationBus::Router::BusRouterDisconnect(); EditorEntityVisibilityNotificationBus::Router::BusRouterDisconnect(); @@ -3571,7 +3576,7 @@ namespace AzToolsFramework void EditorTransformComponentSelection::LeftComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes) { - SetViewportUiClusterVisible(m_transformModeClusterId, true); + SetAllViewportUiVisible(true); ToolsApplicationNotificationBus::Handler::BusConnect(); EditorEntityVisibilityNotificationBus::Router::BusRouterConnect(); @@ -3629,14 +3634,12 @@ namespace AzToolsFramework void EditorTransformComponentSelection::OnStartPlayInEditor() { - SetViewportUiClusterVisible(m_transformModeClusterId, false); - SetViewportUiClusterVisible(m_spaceCluster.m_spaceClusterId, false); + SetAllViewportUiVisible(false); } void EditorTransformComponentSelection::OnStopPlayInEditor() { - SetViewportUiClusterVisible(m_transformModeClusterId, true); - SetViewportUiClusterVisible(m_spaceCluster.m_spaceClusterId, true); + SetAllViewportUiVisible(true); } namespace ETCS diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h index ccff1056ce..1d72328d2d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h @@ -265,7 +265,7 @@ namespace AzToolsFramework void EnteredComponentMode(const AZStd::vector& componentModeTypes) override; void LeftComponentMode(const AZStd::vector& componentModeTypes) override; - // EditorEntityContextNotificationBus ... + // EditorEntityContextNotificationBus overrides ... void OnStartPlayInEditor() override; void OnStopPlayInEditor() override; @@ -279,6 +279,9 @@ namespace AzToolsFramework // Responsible for keeping the space cluster in sync with the current reference frame. void UpdateSpaceCluster(ReferenceFrame referenceFrame); + // Hides/Shows all viewportUi toolbars. + void SetAllViewportUiVisible(const bool visible); + AZ::EntityId m_hoveredEntityId; //!< What EntityId is the mouse currently hovering over (if any). AZ::EntityId m_cachedEntityIdUnderCursor; //!< Store the EntityId on each mouse move for use in Display. AZ::EntityId m_editorCameraComponentEntityId; //!< The EditorCameraComponent EntityId if it is set. From 8408f6b815e41b3de0b5b214ffdbf23c2fa7e6cf Mon Sep 17 00:00:00 2001 From: hasareej Date: Fri, 11 Jun 2021 14:10:02 +0100 Subject: [PATCH 04/17] PR feedback changes 2.0 Signed-off-by: hultonha --- .../ViewportSelection/EditorTransformComponentSelection.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h index 1d72328d2d..25af003930 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h @@ -276,11 +276,11 @@ namespace AzToolsFramework void SetEntityLocalScale(AZ::EntityId entityId, float localScale); void SetEntityLocalRotation(AZ::EntityId entityId, const AZ::Vector3& localRotation); - // Responsible for keeping the space cluster in sync with the current reference frame. + //! Responsible for keeping the space cluster in sync with the current reference frame. void UpdateSpaceCluster(ReferenceFrame referenceFrame); - // Hides/Shows all viewportUi toolbars. - void SetAllViewportUiVisible(const bool visible); + //! Hides/Shows all viewportUi toolbars. + void SetAllViewportUiVisible(bool visible); AZ::EntityId m_hoveredEntityId; //!< What EntityId is the mouse currently hovering over (if any). AZ::EntityId m_cachedEntityIdUnderCursor; //!< Store the EntityId on each mouse move for use in Display. From d2d8e8bc3e928902f60e8c9a25b3e6078380538e Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Wed, 30 Jun 2021 13:35:27 -0500 Subject: [PATCH 05/17] unsigned to unsigned int Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> --- .../SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp index 6ae228a8a8..84b95e5276 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp @@ -63,11 +63,11 @@ namespace AZ } } - for (unsigned meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) + for (unsigned int meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) { const aiMesh* mesh = scene->mMeshes[meshIndex]; - for (unsigned boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex) + for (unsigned int boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex) { const aiBone* bone = mesh->mBones[boneIndex]; From 0a241d8fd0bfca98d6bba68945a53afa5beb8a33 Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Wed, 30 Jun 2021 13:45:51 -0500 Subject: [PATCH 06/17] Bump version Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> --- .../SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp index 84b95e5276..6dec5f93aa 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp @@ -36,7 +36,7 @@ namespace AZ SerializeContext* serializeContext = azrtti_cast(context); if (serializeContext) { - serializeContext->Class()->Version(1); + serializeContext->Class()->Version(2); } } From 4c28c9d89484911db4e31f73aec8d41c11691429 Mon Sep 17 00:00:00 2001 From: guthadam Date: Wed, 30 Jun 2021 17:14:34 -0500 Subject: [PATCH 07/17] ATOM-15908 Fixed material component exporter to use correct relative paths Signed-off-by: guthadam --- .../Material/EditorMaterialComponentUtil.cpp | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentUtil.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentUtil.cpp index f6237b219b..a14751f5ec 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentUtil.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentUtil.cpp @@ -96,8 +96,11 @@ namespace AZ bool SaveSourceMaterialFromEditData(const AZStd::string& path, const MaterialEditData& editData) { - // Getting the source info for the material type file to make sure that it exists - // We also need to watch folder to generate a relative asset path for the material type + // Construct the material source data object that will be exported + AZ::RPI::MaterialSourceData exportData; + exportData.m_propertyLayoutVersion = editData.m_materialTypeSourceData.m_propertyLayout.m_version; + + // Converting absolute material paths to relative paths bool result = false; AZ::Data::AssetInfo info; AZStd::string watchFolder; @@ -106,22 +109,30 @@ namespace AZ editData.m_materialTypeSourcePath.c_str(), info, watchFolder); if (!result) { - AZ_Error("AZ::Render::EditorMaterialComponentUtil", false, "Failed to get source file info and asset path while attempting to export: %s", path.c_str()); + AZ_Error( + "AZ::Render::EditorMaterialComponentUtil", false, + "Failed to get material type source file info while attempting to export: %s", path.c_str()); return false; } - // Construct the material source data object that will be exported - AZ::RPI::MaterialSourceData exportData; - exportData.m_propertyLayoutVersion = editData.m_materialTypeSourceData.m_propertyLayout.m_version; + exportData.m_materialType = info.m_relativePath; - // Converting absolute material paths to asset relative paths - exportData.m_materialType = editData.m_materialTypeSourcePath; - AzFramework::ApplicationRequests::Bus::Broadcast( - &AzFramework::ApplicationRequests::Bus::Events::MakePathRelative, exportData.m_materialType, watchFolder.c_str()); + if (!editData.m_materialParentSourcePath.empty()) + { + result = false; + AzToolsFramework::AssetSystemRequestBus::BroadcastResult( + result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, + editData.m_materialParentSourcePath.c_str(), info, watchFolder); + if (!result) + { + AZ_Error( + "AZ::Render::EditorMaterialComponentUtil", false, + "Failed to get parent material source file info while attempting to export: %s", path.c_str()); + return false; + } - exportData.m_parentMaterial = editData.m_materialParentSourcePath; - AzFramework::ApplicationRequests::Bus::Broadcast( - &AzFramework::ApplicationRequests::Bus::Events::MakePathRelative, exportData.m_parentMaterial, watchFolder.c_str()); + exportData.m_parentMaterial = info.m_relativePath; + } // Copy all of the properties from the material asset to the source data that will be exported result = true; From 899350b5c72c05c86d3ce5d41b25dbe2d1918ead Mon Sep 17 00:00:00 2001 From: greerdv Date: Thu, 1 Jul 2021 11:24:10 +0100 Subject: [PATCH 08/17] bring across lua raycast improvements from 1.x Signed-off-by: greerdv --- .../Physics/Collision/CollisionGroups.cpp | 26 ++- .../Physics/Common/PhysicsSceneQueries.cpp | 17 +- .../AzFramework/AzFramework/Physics/Utils.cpp | 29 ++-- Gems/PhysX/Code/Source/Shape.cpp | 6 + Gems/PhysX/Code/Tests/PhysXScriptTest.cpp | 154 ++++++++++++++++++ Gems/PhysX/Code/physx_tests_files.cmake | 1 + 6 files changed, 214 insertions(+), 19 deletions(-) create mode 100644 Gems/PhysX/Code/Tests/PhysXScriptTest.cpp diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp index 36bd7178c1..f8cc37156e 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp @@ -34,6 +34,28 @@ namespace AzPhysics const CollisionGroup CollisionGroup::All_NoTouchBend = CollisionGroup::All.GetMask() & ~CollisionLayer::TouchBend.GetMask(); #endif + void CollisionGroupScriptConstructor(CollisionGroup* thisPtr, AZ::ScriptDataContext& scriptDataContext) + { + int numArgs = scriptDataContext.GetNumArguments(); + if (numArgs != 1) + { + scriptDataContext.GetScriptContext()->Error(AZ::ScriptContext::ErrorType::Error, true, + "CollisionGroup() accepts only 1 argument, not %d", numArgs); + return; + } + + if (!scriptDataContext.IsString(0)) + { + scriptDataContext.GetScriptContext()->Error(AZ::ScriptContext::ErrorType::Error, true, + "Argument to CollisionGroup() should be string"); + return; + } + + AZStd::string groupName; + scriptDataContext.ReadArg(0, groupName); + *thisPtr = CollisionGroup(groupName); + } + void CollisionGroup::Reflect(AZ::ReflectContext* context) { if (auto* serializeContext = azrtti_cast(context)) @@ -50,7 +72,9 @@ namespace AzPhysics ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) ->Attribute(AZ::Script::Attributes::Module, "physics") ->Attribute(AZ::Script::Attributes::Category, "AzPhysics") - ->Constructor() + ->Constructor() + ->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value) + ->Attribute(AZ::Script::Attributes::ConstructorOverride, &CollisionGroupScriptConstructor) ; } } diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsSceneQueries.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsSceneQueries.cpp index 92cd89a801..30e0cde9df 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsSceneQueries.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsSceneQueries.cpp @@ -88,6 +88,19 @@ namespace AzPhysics ; } } + + if (auto* behaviorContext = azdynamic_cast(context)) + { + behaviorContext->Class("SceneQueryRequest") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Module, "physics") + ->Attribute(AZ::Script::Attributes::Category, "PhysX") + ->Property("Collision", BehaviorValueProperty(&SceneQueryRequest::m_collisionGroup)) + // Until enum class support for behavior context is done, expose this as an int + ->Property("QueryType", [](const SceneQueryRequest& self) { return static_cast(self.m_queryType); }, + [](SceneQueryRequest& self, int newQueryType) { self.m_queryType = SceneQuery::QueryType(newQueryType); }) + ; + } } /*static*/ void RayCastRequest::Reflect(AZ::ReflectContext* context) @@ -123,10 +136,6 @@ namespace AzPhysics ->Property("Distance", BehaviorValueProperty(&RayCastRequest::m_distance)) ->Property("Start", BehaviorValueProperty(&RayCastRequest::m_start)) ->Property("Direction", BehaviorValueProperty(&RayCastRequest::m_direction)) - ->Property("Collision", BehaviorValueProperty(&RayCastRequest::m_collisionGroup)) - // Until enum class support for behavior context is done, expose this as an int - ->Property("QueryType", [](const RayCastRequest& self) { return static_cast(self.m_queryType); }, - [](RayCastRequest& self, int newQueryType) { self.m_queryType = SceneQuery::QueryType(newQueryType); }) ; } } diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Utils.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Utils.cpp index 809b4a2b0f..6498b6afce 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Utils.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Utils.cpp @@ -73,21 +73,22 @@ namespace Physics { if (auto behaviorContext = azrtti_cast(context)) { - behaviorContext->EBus("CharacterControllerRequestBus", "Character Controller") - ->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::RuntimeOwn) + behaviorContext->EBus("CharacterControllerRequestBus") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Module, "physics") ->Attribute(AZ::Edit::Attributes::Category, "PhysX") - ->Event("GetBasePosition", &Physics::CharacterRequests::GetBasePosition, "Get Base Position") - ->Event("SetBasePosition", &Physics::CharacterRequests::SetBasePosition, "Set Base Position") - ->Event("GetCenterPosition", &Physics::CharacterRequests::GetCenterPosition, "Get Center Position") - ->Event("GetStepHeight", &Physics::CharacterRequests::GetStepHeight, "Get Step Height") - ->Event("SetStepHeight", &Physics::CharacterRequests::SetStepHeight, "Set Step Height") - ->Event("GetUpDirection", &Physics::CharacterRequests::GetUpDirection, "Get Up Direction") - ->Event("GetSlopeLimitDegrees", &Physics::CharacterRequests::GetSlopeLimitDegrees, "Get Slope Limit (Degrees)") - ->Event("SetSlopeLimitDegrees", &Physics::CharacterRequests::SetSlopeLimitDegrees, "Set Slope Limit (Degrees)") - ->Event("GetMaximumSpeed", &Physics::CharacterRequests::GetMaximumSpeed, "Get Maximum Speed") - ->Event("SetMaximumSpeed", &Physics::CharacterRequests::SetMaximumSpeed, "Set Maximum Speed") - ->Event("GetVelocity", &Physics::CharacterRequests::GetVelocity, "Get Velocity") - ->Event("AddVelocity", &Physics::CharacterRequests::AddVelocity, "Add Velocity") + ->Event("GetBasePosition", &CharacterRequests::GetBasePosition, "Get Base Position") + ->Event("SetBasePosition", &CharacterRequests::SetBasePosition, "Set Base Position") + ->Event("GetCenterPosition", &CharacterRequests::GetCenterPosition, "Get Center Position") + ->Event("GetStepHeight", &CharacterRequests::GetStepHeight, "Get Step Height") + ->Event("SetStepHeight", &CharacterRequests::SetStepHeight, "Set Step Height") + ->Event("GetUpDirection", &CharacterRequests::GetUpDirection, "Get Up Direction") + ->Event("GetSlopeLimitDegrees", &CharacterRequests::GetSlopeLimitDegrees, "Get Slope Limit (Degrees)") + ->Event("SetSlopeLimitDegrees", &CharacterRequests::SetSlopeLimitDegrees, "Set Slope Limit (Degrees)") + ->Event("GetMaximumSpeed", &CharacterRequests::GetMaximumSpeed, "Get Maximum Speed") + ->Event("SetMaximumSpeed", &CharacterRequests::SetMaximumSpeed, "Set Maximum Speed") + ->Event("GetVelocity", &CharacterRequests::GetVelocity, "Get Velocity") + ->Event("AddVelocity", &CharacterRequests::AddVelocity, "Add Velocity") ; } } diff --git a/Gems/PhysX/Code/Source/Shape.cpp b/Gems/PhysX/Code/Source/Shape.cpp index b29e407e0c..129bfa9774 100644 --- a/Gems/PhysX/Code/Source/Shape.cpp +++ b/Gems/PhysX/Code/Source/Shape.cpp @@ -326,6 +326,12 @@ namespace PhysX AzPhysics::SceneQueryHit Shape::RayCastInternal(const AzPhysics::RayCastRequest& worldSpaceRequest, const physx::PxTransform& pose) { + if (const bool shouldCollide = worldSpaceRequest.m_collisionGroup.GetMask() & m_collisionLayer.GetMask(); + !shouldCollide) + { + return AzPhysics::SceneQueryHit(); + } + const physx::PxVec3 start = PxMathConvert(worldSpaceRequest.m_start); const physx::PxVec3 unitDir = PxMathConvert(worldSpaceRequest.m_direction); const physx::PxU32 maxHits = 1; diff --git a/Gems/PhysX/Code/Tests/PhysXScriptTest.cpp b/Gems/PhysX/Code/Tests/PhysXScriptTest.cpp new file mode 100644 index 0000000000..ac9a731d54 --- /dev/null +++ b/Gems/PhysX/Code/Tests/PhysXScriptTest.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include "PhysXTestFixtures.h" +#include "PhysXTestUtil.h" +#include "PhysXTestCommon.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace PhysX +{ + static AZStd::map s_testEntities; + + AZ::EntityId GetTestEntityId(const char* name) + { + if (auto it = s_testEntities.find(name); + it != s_testEntities.end()) + { + return it->second->GetId(); + } + + return AZ::EntityId(); + } + + void ExpectTrue(bool check) + { + EXPECT_TRUE(check); + } + + class PhysXScriptTest + : public PhysXDefaultWorldTest + { + public: + AZ_TYPE_INFO(PhysXScriptTest, "{337A9DB4-ACF7-42A7-92E5-48A9FF14B49C}"); + + void SetUp() override + { + PhysXDefaultWorldTest::SetUp(); + + m_behaviorContext = AZStd::make_unique(); + AZ::Entity::Reflect(m_behaviorContext.get()); + AZ::MathReflect(m_behaviorContext.get()); + AzFramework::EntityContext::Reflect(m_behaviorContext.get()); + Physics::ReflectionUtils::ReflectPhysicsApi(m_behaviorContext.get()); + m_behaviorContext->Method("ExpectTrue", &ExpectTrue); + m_behaviorContext->Method("GetTestEntityId", &GetTestEntityId); + m_scriptContext = AZStd::make_unique(); + m_scriptContext->BindTo(m_behaviorContext.get()); + } + + void TearDown() override + { + s_testEntities.clear(); + + m_scriptContext.reset(); + m_behaviorContext.reset(); + + PhysXDefaultWorldTest::TearDown(); + } + + AZ::BehaviorContext* GetBehaviorContext() + { + return m_behaviorContext.get(); + } + + AZ::ScriptContext* GetScriptContext() + { + return m_scriptContext.get(); + } + + private: + AZStd::unique_ptr m_behaviorContext; + AZStd::unique_ptr m_scriptContext; + }; + + TEST_F(PhysXScriptTest, ScriptedRaycast_RaycastNotIntersectingBox_ReturnsNoHits) + { + s_testEntities.insert( + { + "Box", + TestUtils::AddStaticUnitTestObject(GetDefaultSceneHandle(), AZ::Vector3::CreateZero(), "Box") + }); + + const char luaCode[] = + R"( + boxId = GetTestEntityId("Box") + request = RayCastRequest() + request.Start = Vector3(5.0, 0.0, 5.0) + request.Direction = Vector3(0.0, 0.0, -1.0) + request.Distance = 10.0 + hit = SimulatedBodyComponentRequestBus.Event.RayCast(boxId, request) + ExpectTrue(hit.EntityId == EntityId()) + )"; + + EXPECT_TRUE(GetScriptContext()->Execute(luaCode)); + } + + TEST_F(PhysXScriptTest, ScriptedRaycast_RaycastIntersectingBox_ReturnsHitOnBox) + { + s_testEntities.insert( + { + "Box", + TestUtils::AddStaticUnitTestObject(GetDefaultSceneHandle(), AZ::Vector3::CreateZero(), "Box") + }); + + const char luaCode[] = + R"( + boxId = GetTestEntityId("Box") + request = RayCastRequest() + request.Start = Vector3(0.0, 0.0, 5.0) + request.Direction = Vector3(0.0, 0.0, -1.0) + request.Distance = 10.0 + hit = SimulatedBodyComponentRequestBus.Event.RayCast(boxId, request) + ExpectTrue(hit.EntityId == boxId) + )"; + + EXPECT_TRUE(GetScriptContext()->Execute(luaCode)); + } + + TEST_F(PhysXScriptTest, ScriptedRaycast_RaycastNotInteractingCollisionFilters_ReturnsNoHit) + { + s_testEntities.insert( + { + "Box", + TestUtils::AddStaticUnitTestObject(GetDefaultSceneHandle(), AZ::Vector3::CreateZero(), "Box") + }); + + const char luaCode[] = + R"( + boxId = GetTestEntityId("Box") + request = RayCastRequest() + request.Start = Vector3(0.0, 0.0, 5.0) + request.Direction = Vector3(0.0, 0.0, -1.0) + request.Distance = 10.0 + request.Collision = CollisionGroup("None") + hit = SimulatedBodyComponentRequestBus.Event.RayCast(boxId, request) + ExpectTrue(hit.EntityId == EntityId()) + )"; + + EXPECT_TRUE(GetScriptContext()->Execute(luaCode)); + } +} // namespace PhysX diff --git a/Gems/PhysX/Code/physx_tests_files.cmake b/Gems/PhysX/Code/physx_tests_files.cmake index 09ecf19de5..d42e872d5d 100644 --- a/Gems/PhysX/Code/physx_tests_files.cmake +++ b/Gems/PhysX/Code/physx_tests_files.cmake @@ -29,6 +29,7 @@ set(FILES Tests/PhysXTestUtil.h Tests/PhysXTestUtil.cpp Tests/PhysXMultithreadingTest.cpp + Tests/PhysXScriptTest.cpp Tests/CharacterControllerTests.cpp Tests/RagdollConfiguration.xml Tests/RagdollTestData.h From 05a2ce4fe19fbc014975b1802b5408ac939d49d7 Mon Sep 17 00:00:00 2001 From: greerdv Date: Thu, 1 Jul 2021 13:35:57 +0100 Subject: [PATCH 09/17] update based on PR feedback Signed-off-by: greerdv --- .../AzFramework/Physics/Collision/CollisionGroups.cpp | 4 ++-- Gems/PhysX/Code/Tests/PhysXScriptTest.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp index 3aab358aa4..a8c8c4470f 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp @@ -36,8 +36,8 @@ namespace AzPhysics void CollisionGroupScriptConstructor(CollisionGroup* thisPtr, AZ::ScriptDataContext& scriptDataContext) { - int numArgs = scriptDataContext.GetNumArguments(); - if (numArgs != 1) + if (int numArgs = scriptDataContext.GetNumArguments(); + numArgs != 1) { scriptDataContext.GetScriptContext()->Error(AZ::ScriptContext::ErrorType::Error, true, "CollisionGroup() accepts only 1 argument, not %d", numArgs); diff --git a/Gems/PhysX/Code/Tests/PhysXScriptTest.cpp b/Gems/PhysX/Code/Tests/PhysXScriptTest.cpp index ac9a731d54..7491ffe2f4 100644 --- a/Gems/PhysX/Code/Tests/PhysXScriptTest.cpp +++ b/Gems/PhysX/Code/Tests/PhysXScriptTest.cpp @@ -34,6 +34,8 @@ namespace PhysX return AZ::EntityId(); } + // this allows EXPECT_TRUE to be exposed to the behavior context and used inside blocks of lua code which + // are executed in tests void ExpectTrue(bool check) { EXPECT_TRUE(check); From ef1c6732c8f174ccdb1941d898ee6e5651972cee Mon Sep 17 00:00:00 2001 From: greerdv Date: Thu, 1 Jul 2021 14:11:47 +0100 Subject: [PATCH 10/17] fix licence on new file Signed-off-by: greerdv --- Gems/PhysX/Code/Tests/PhysXScriptTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/PhysX/Code/Tests/PhysXScriptTest.cpp b/Gems/PhysX/Code/Tests/PhysXScriptTest.cpp index 7491ffe2f4..40213dedcf 100644 --- a/Gems/PhysX/Code/Tests/PhysXScriptTest.cpp +++ b/Gems/PhysX/Code/Tests/PhysXScriptTest.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) Contributors to the Open 3D Engine Project - * + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ From 4c4be73bd55d38ee2147e3ad08ffde6ba6afdac0 Mon Sep 17 00:00:00 2001 From: AMZN-stankowi <4838196+AMZN-stankowi@users.noreply.github.com> Date: Thu, 1 Jul 2021 08:53:47 -0700 Subject: [PATCH 11/17] First pass FBX -> Scene File conversion. (#1699) This is the simple pass, minimizing code changes and focused on comments. Signed-off-by: stankowi <4838196+AMZN-stankowi@users.noreply.github.com> --- .../RPI.Builders/Model/MaterialAssetBuilderComponent.cpp | 6 +++--- .../RPI.Builders/Model/ModelAssetBuilderComponent.cpp | 2 +- .../Source/Material/EditorMaterialComponentExporter.cpp | 2 +- .../Code/Source/Material/MaterialThumbnail.cpp | 2 +- .../EMotionFXAtom/Code/Source/ActorAsset.cpp | 2 +- Gems/Blast/Code/Source/Asset/BlastAsset.cpp | 2 +- .../EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.cpp | 2 +- .../SceneAPIExt/Behaviors/MotionRangeRuleBehavior.cpp | 2 +- .../EMotionFX/Pipeline/SceneAPIExt/Groups/IMotionGroup.h | 2 +- .../Code/EMotionFX/Source/MotionData/MotionData.h | 2 +- .../EMotionFX/Source/MotionData/NonUniformMotionData.cpp | 2 +- .../EMotionFX/Source/MotionData/NonUniformMotionData.h | 2 +- .../EMotionFX/Source/MotionData/UniformMotionData.cpp | 2 +- .../Code/EMotionFX/Source/MotionData/UniformMotionData.h | 2 +- .../Source/Editor/PropertyWidgets/MotionDataHandler.cpp | 2 +- .../Integration/Editor/Components/EditorActorComponent.h | 2 +- .../Code/Source/Integration/System/SystemComponent.cpp | 2 +- Gems/EMotionFX/Code/Tests/Game/SamplePerformanceTests.cpp | 4 ++-- Gems/EMotionFX/Code/Tests/UI/CanUseFileMenu.cpp | 4 ++-- .../Code/include/LmbrCentral/Rendering/MaterialAsset.h | 4 ++-- .../Code/Source/Components/EditorClothComponent.cpp | 2 +- Gems/NvCloth/Code/Source/Editor/MeshNodeHandler.cpp | 6 +++--- .../Code/Source/Pipeline/SceneAPIExt/ClothRule.cpp | 2 +- .../Source/Pipeline/SceneAPIExt/ClothRuleBehavior.cpp | 2 +- .../Code/Source/Pipeline/SceneAPIExt/ClothRuleBehavior.h | 2 +- Gems/PhysX/Code/Source/EditorColliderComponent.cpp | 2 +- Gems/PhysX/Code/Source/Pipeline/MeshAssetHandler.cpp | 2 +- Gems/PhysX/Code/Source/Pipeline/MeshExporter.cpp | 8 ++++---- Gems/PhysX/Code/Source/Pipeline/MeshExporter.h | 2 +- .../Code/Include/Config/SceneProcessingConfigBus.h | 2 +- .../Components/SceneProcessingConfigSystemComponent.cpp | 4 ++-- .../TangentGenerator/TangentGenerateComponent.cpp | 8 ++++---- .../Code/Source/SceneBuilder/SceneBuilderWorker.cpp | 4 ++-- 33 files changed, 48 insertions(+), 48 deletions(-) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp index a7ee299989..91c9803955 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MaterialAssetBuilderComponent.cpp @@ -69,7 +69,7 @@ namespace AZ void MaterialAssetDependenciesComponent::ReportJobDependencies(SceneAPI::JobDependencyList& jobDependencyList, const char* platformIdentifier) { AssetBuilderSDK::SourceFileDependency materialTypeSource; - // Right now, FBX importing only supports a single material type, once that changes, this will have to be re-designed, see ATOM-3554 + // Right now, scene file importing only supports a single material type, once that changes, this will have to be re-designed, see ATOM-3554 RPI::MaterialConverterBus::BroadcastResult(materialTypeSource.m_sourceFileDependencyPath, &RPI::MaterialConverterBus::Events::GetMaterialTypePath); AssetBuilderSDK::JobDependency jobDependency; @@ -94,7 +94,7 @@ namespace AZ { // [GFX TODO] I am suggesting we use the first two 16bits for different kind of assets generated from a Scene // For example, 0x10000 for mesh, 0x20000 for material, 0x30000 for animation, 0x40000 for scene graph and etc. - // so the subid can be evaluated for reference across different assets generate within this fbx. + // so the subid can be evaluated for reference across different assets generate within this scene file. /*const uint32_t materialPrefix = 0x20000; AZ_Assert(materialPrefix > materialId, "materialId should be smaller than materialPrefix"); return materialPrefix + materialId;*/ @@ -148,7 +148,7 @@ namespace AZ // The source data for generating material asset MaterialSourceData sourceData; - // User hook to create their materials based on the data from Fbx pipeline + // User hook to create their materials based on the data from the scene pipeline bool result = false; RPI::MaterialConverterBus::BroadcastResult(result, &RPI::MaterialConverterBus::Events::ConvertMaterial, *materialData, sourceData); if (result) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/ModelAssetBuilderComponent.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/ModelAssetBuilderComponent.cpp index 0b5cbb96ca..bfb0979d5c 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/ModelAssetBuilderComponent.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/ModelAssetBuilderComponent.cpp @@ -995,7 +995,7 @@ namespace AZ if (numInfluencesExcess > 0) { AZ_Warning(s_builderName, warnedExcessOfSkinInfluences, - "Mesh %s has more skin influences (%d) than the maximum (%d). Skinning influences won't be normalized. Maximum number of skin influences can be increased with a Skin Modifier in FBX Settings.", + "Mesh %s has more skin influences (%d) than the maximum (%d). Skinning influences won't be normalized. Maximum number of skin influences can be increased with a Skin Modifier in Scene Settings.", sourceMesh.m_name.GetCStr(), m_numSkinJointInfluencesPerVertex + numInfluencesExcess, m_numSkinJointInfluencesPerVertex); diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentExporter.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentExporter.cpp index f917a4bcc2..0a311a4a81 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentExporter.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentExporter.cpp @@ -41,7 +41,7 @@ namespace AZ AZStd::string label; if (assetId.IsValid()) { - // Material assets that are exported through the FBX pipeline have their filenames generated by adding + // Material assets that are exported through the scene pipeline have their filenames generated by adding // the DCC material name as a prefix and a unique number to the end of the source file name. // Rather than storing the DCC material name inside of the material asset we can reproduce it by removing // the prefix and suffix from the product file name. diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/MaterialThumbnail.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/MaterialThumbnail.cpp index ff37a51bfc..a850a5c9e8 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/MaterialThumbnail.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/MaterialThumbnail.cpp @@ -100,7 +100,7 @@ namespace AZ { return GetAssetId(key, RPI::MaterialAsset::RTTI_Type()).IsValid() && - // in case it's a source fbx, it will contain both material and model products + // in case it's a source scene file, it will contain both material and model products // model thumbnails are handled by MeshThumbnail !GetAssetId(key, RPI::ModelAsset::RTTI_Type()).IsValid(); } diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorAsset.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorAsset.cpp index 9d686f9bba..7a32fdc385 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorAsset.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorAsset.cpp @@ -95,7 +95,7 @@ namespace AZ skinnedSubMesh.m_vertexCount = aznumeric_cast(subMeshVertexCount); lodVertexCount += aznumeric_cast(subMeshVertexCount); - // The default material id used by a sub-mesh is the guid of the source .fbx plus the subId which is a unique material ID from the scene API + // The default material id used by a sub-mesh is the guid of the source scene file plus the subId which is a unique material ID from the scene API AZ::u32 subId = modelMesh.GetMaterialAsset().GetId().m_subId; AZ::Data::AssetId materialId{ actorAssetId.m_guid, subId }; diff --git a/Gems/Blast/Code/Source/Asset/BlastAsset.cpp b/Gems/Blast/Code/Source/Asset/BlastAsset.cpp index dc5f315a7f..932bb79bcb 100644 --- a/Gems/Blast/Code/Source/Asset/BlastAsset.cpp +++ b/Gems/Blast/Code/Source/Asset/BlastAsset.cpp @@ -62,7 +62,7 @@ namespace Blast } else { - // in this case we'll want to extract the physics meshes from the fbx. + // in this case we'll want to extract the physics meshes from the scene file. // We don't necessarily have access to the mesh data though, so if we want to support this, // we'll need to come up with a way to associate with the mesh data // See BlastAssetModel in the SDK sample for how to create that data diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.cpp index 64ca2b68dc..7f5558c1da 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.cpp @@ -160,7 +160,7 @@ namespace EMotionFX } } - // Default to the first mesh group until we get a way to choose it via the FBX settings (ATOM-13590). + // Default to the first mesh group until we get a way to choose it via the scene settings (ATOM-13590). AZStd::optional meshAssetId = AZStd::nullopt; AZ_Error("EMotionFX", atomModelAssets.size() <= 1, "Ambigious mesh for actor asset. More than one mesh group found. Defaulting to the first one."); if (!atomModelAssets.empty()) diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/MotionRangeRuleBehavior.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/MotionRangeRuleBehavior.cpp index e2847ac75c..083fd49d3e 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/MotionRangeRuleBehavior.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/MotionRangeRuleBehavior.cpp @@ -96,7 +96,7 @@ namespace EMotionFX const AZ::u32 frameCount = aznumeric_caster(animation->GetKeyFrameCount()); if (motionRangeRule->GetStartFrame() == 0 && motionRangeRule->GetEndFrame() == frameCount - 1) { - // if the startframe/endframe matches the fbx animation length, remove it. + // if the startframe/endframe matches the scene file's animation length, remove it. rules.RemoveRule(motionRangeRule); updated = true; } diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Groups/IMotionGroup.h b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Groups/IMotionGroup.h index ec8e926544..29c561051b 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Groups/IMotionGroup.h +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Groups/IMotionGroup.h @@ -25,7 +25,7 @@ namespace EMotionFX ~IMotionGroup() override = default; // Ability to specify root bone can be useful if there are multiple skeletons - // stored in an fbx file or if the user wants to override the root bone automatically + // stored in a scene file or if the user wants to override the root bone automatically // selected by the code. virtual const AZStd::string& GetSelectedRootBone() const = 0; diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/MotionData.h b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/MotionData.h index d018e8c50d..fbbd50be68 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/MotionData.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/MotionData.h @@ -158,7 +158,7 @@ namespace EMotionFX virtual size_t CalcStreamSaveSizeInBytes(const SaveSettings& saveSettings) const = 0; virtual AZ::u32 GetStreamSaveVersion() const = 0; virtual bool GetSupportsOptimizeSettings() const { return true; } - virtual const char* GetFbxSettingsName() const = 0; + virtual const char* GetSceneSettingsName() const = 0; // Sampling virtual Transform SampleJointTransform(const SampleSettings& settings, AZ::u32 jointSkeletonIndex) const = 0; diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.cpp index 9368e74950..f9e0911d51 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.cpp @@ -35,7 +35,7 @@ namespace EMotionFX return aznew NonUniformMotionData(); } - const char* NonUniformMotionData::GetFbxSettingsName() const + const char* NonUniformMotionData::GetSceneSettingsName() const { return "Reduced Keyframes (slower, mostly smaller)"; } diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.h b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.h index abb633f1a7..ec2ddff0ad 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.h @@ -52,7 +52,7 @@ namespace EMotionFX bool Save(MCore::Stream* stream, const SaveSettings& saveSettings) const override; size_t CalcStreamSaveSizeInBytes(const SaveSettings& saveSettings) const override; AZ::u32 GetStreamSaveVersion() const override; - const char* GetFbxSettingsName() const override; + const char* GetSceneSettingsName() const override; Transform SampleJointTransform(const SampleSettings& settings, AZ::u32 jointSkeletonIndex) const override; void SamplePose(const SampleSettings& settings, Pose* outputPose) const override; diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.cpp index a74ee8c45f..296f4adf62 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.cpp @@ -36,7 +36,7 @@ namespace EMotionFX return aznew UniformMotionData(); } - const char* UniformMotionData::GetFbxSettingsName() const + const char* UniformMotionData::GetSceneSettingsName() const { return "Evenly Spaced Keyframes (faster, mostly larger)"; } diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.h b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.h index 3b8ff21d58..c92ce192b2 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.h @@ -49,7 +49,7 @@ namespace EMotionFX size_t CalcStreamSaveSizeInBytes(const SaveSettings& saveSettings) const override; AZ::u32 GetStreamSaveVersion() const override; bool GetSupportsOptimizeSettings() const override { return false; } - const char* GetFbxSettingsName() const override; + const char* GetSceneSettingsName() const override; // Overloaded. Transform SampleJointTransform(const SampleSettings& settings, AZ::u32 jointSkeletonIndex) const override; diff --git a/Gems/EMotionFX/Code/Source/Editor/PropertyWidgets/MotionDataHandler.cpp b/Gems/EMotionFX/Code/Source/Editor/PropertyWidgets/MotionDataHandler.cpp index e3dbe7efb4..94c90f4676 100644 --- a/Gems/EMotionFX/Code/Source/Editor/PropertyWidgets/MotionDataHandler.cpp +++ b/Gems/EMotionFX/Code/Source/Editor/PropertyWidgets/MotionDataHandler.cpp @@ -76,7 +76,7 @@ namespace EMotionFX const MotionDataFactory& factory = GetEMotionFX().GetMotionManager()->GetMotionDataFactory(); for (size_t i = 0; i < factory.GetNumRegistered(); ++i) { - GUI->addItem(factory.GetRegistered(i)->GetFbxSettingsName()); + GUI->addItem(factory.GetRegistered(i)->GetSceneSettingsName()); m_typeIds.emplace_back(factory.GetRegistered(i)->RTTI_GetType()); } diff --git a/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.h b/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.h index 6d7d876954..1629e07fdd 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.h +++ b/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.h @@ -161,7 +161,7 @@ namespace EMotionFX bool m_forceUpdateJointsOOV = false; // \todo attachmentTarget node nr - // Note: LOD work in progress. For now we use one material instead of a list of material, because we don't have the support for LOD with multiple FBXs. + // Note: LOD work in progress. For now we use one material instead of a list of material, because we don't have the support for LOD with multiple scene files. // We purposely kept a materialList in actorComponent and actorRenderNode for the flexibility in future. // At the moment, the materialList stores duplicates of the same material. AzFramework::SimpleAssetReference m_materialPerActor; diff --git a/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp b/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp index 131ff2ff7c..b0384c7577 100644 --- a/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp @@ -485,7 +485,7 @@ namespace EMotionFX SetMediaRoot("@assets@"); // \todo Right now we're pointing at the @devassets@ location (source) and working from there, because .actor and .motion (motion) aren't yet processed through - // the FBX pipeline. Once they are, we'll need to update various segments of the Tool to always read from the @assets@ cache, but write to the @devassets@ data/metadata. + // the scene pipeline. Once they are, we'll need to update various segments of the Tool to always read from the @assets@ cache, but write to the @devassets@ data/metadata. EMotionFX::GetEMotionFX().InitAssetFolderPaths(); // Register EMotionFX event handler diff --git a/Gems/EMotionFX/Code/Tests/Game/SamplePerformanceTests.cpp b/Gems/EMotionFX/Code/Tests/Game/SamplePerformanceTests.cpp index 87f4b46955..96e5014304 100644 --- a/Gems/EMotionFX/Code/Tests/Game/SamplePerformanceTests.cpp +++ b/Gems/EMotionFX/Code/Tests/Game/SamplePerformanceTests.cpp @@ -770,13 +770,13 @@ namespace EMotionFX TEST_F(PerformanceTestFixture, DISABLED_MotionSamplingPerformanceNonUniform) { - // Make sure that the motion is set to use NonUniform sampling! Change this in the Fbx settings! Otherwise you get wrong results. + // Make sure that the motion is set to use NonUniform sampling! Change this in the scene settings! Otherwise you get wrong results. TestMotionSamplingPerformance("@assets@\\animationsamples\\advanced_rinlocomotion\\motions\\rin_idle.motion"); } TEST_F(PerformanceTestFixture, DISABLED_MotionSamplingPerformanceUniform) { - // Make sure that the motion is set to use Uniform sampling! Change this in the Fbx settings! Otherwise you get wrong results. + // Make sure that the motion is set to use Uniform sampling! Change this in the scene settings! Otherwise you get wrong results. TestMotionSamplingPerformance("@assets@\\animationsamples\\advanced_rinlocomotion\\motions\\rin_walk_kick_01.motion"); } diff --git a/Gems/EMotionFX/Code/Tests/UI/CanUseFileMenu.cpp b/Gems/EMotionFX/Code/Tests/UI/CanUseFileMenu.cpp index f599985cfa..53b9ec8aa4 100644 --- a/Gems/EMotionFX/Code/Tests/UI/CanUseFileMenu.cpp +++ b/Gems/EMotionFX/Code/Tests/UI/CanUseFileMenu.cpp @@ -249,7 +249,7 @@ namespace EMotionFX LoadActor(actorFilename.toUtf8().data(), false); ASSERT_EQ(EMotionFX::GetActorManager().GetNumActorInstances(), 2) << "Failed to merge Actor."; - // We can't test Save Selected Actor as we would it would involve mocking fbx scene handling. + // We can't test Save Selected Actor as we would it would involve mocking source scene handling. // Add the filename to the recent actorsa anyway, so we can test that functionality. EMStudio::GetMainWindow()->AddRecentActorFile(actorFilename); @@ -634,7 +634,7 @@ namespace EMotionFX motionSet->SetFilename(motionsetFilename.toUtf8().constData()); motionSet->SetDirtyFlag(true); - // Don't create an actor or motion as we can't save that due to fbx scene requirements. + // Don't create an actor or motion as we can't save that due to source scene requirements. EMStudio::Workspace* workspace = EMStudio::GetManager()->GetWorkspace(); const QString workspaceFilename = GenerateTempWorkspaceFilename(); diff --git a/Gems/LmbrCentral/Code/include/LmbrCentral/Rendering/MaterialAsset.h b/Gems/LmbrCentral/Code/include/LmbrCentral/Rendering/MaterialAsset.h index 22c41863a8..6ce3861233 100644 --- a/Gems/LmbrCentral/Code/include/LmbrCentral/Rendering/MaterialAsset.h +++ b/Gems/LmbrCentral/Code/include/LmbrCentral/Rendering/MaterialAsset.h @@ -28,8 +28,8 @@ namespace LmbrCentral }; /*! - * FBX Material asset type configuration. - * Reflect as: AzFramework::SimpleAssetReference + * Source scene file Material asset type configuration. + * Reflect as: AzFramework::SimpleAssetReference */ class DccMaterialAsset { diff --git a/Gems/NvCloth/Code/Source/Components/EditorClothComponent.cpp b/Gems/NvCloth/Code/Source/Components/EditorClothComponent.cpp index f2730b0bac..a71866fc6f 100644 --- a/Gems/NvCloth/Code/Source/Components/EditorClothComponent.cpp +++ b/Gems/NvCloth/Code/Source/Components/EditorClothComponent.cpp @@ -68,7 +68,7 @@ namespace NvCloth // Mesh Node ->DataElement(Editor::MeshNodeSelector, &ClothConfiguration::m_meshNode, "Mesh node", - "List of mesh nodes with cloth simulation data. These are the nodes selected inside Cloth Modifiers in FBX Editor Settings.") + "List of mesh nodes with cloth simulation data. These are the nodes selected inside Cloth Modifiers in Scene Settings.") ->Attribute(AZ::Edit::UIHandlers::EntityId, &ClothConfiguration::GetEntityId) ->Attribute(AZ::Edit::Attributes::StringList, &ClothConfiguration::PopulateMeshNodeList) ->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree) diff --git a/Gems/NvCloth/Code/Source/Editor/MeshNodeHandler.cpp b/Gems/NvCloth/Code/Source/Editor/MeshNodeHandler.cpp index 168a5348c1..20a6c91c89 100644 --- a/Gems/NvCloth/Code/Source/Editor/MeshNodeHandler.cpp +++ b/Gems/NvCloth/Code/Source/Editor/MeshNodeHandler.cpp @@ -25,8 +25,8 @@ namespace NvCloth { widget_t* picker = new widget_t(parent); - // Set edit button appearance to go to FBX Settings dialog - picker->GetEditButton()->setToolTip("Open FBX Settings to setup Cloth Modifiers"); + // Set edit button appearance to go to Scene Settings dialog + picker->GetEditButton()->setToolTip("Open Scene Settings to setup Cloth Modifiers"); picker->GetEditButton()->setText(""); picker->GetEditButton()->setEnabled(false); @@ -106,7 +106,7 @@ namespace NvCloth AZ::Data::Asset meshAsset = GetMeshAsset(GUI->GetEntityId()); if (meshAsset) { - // Open the asset with the preferred asset editor, which for Mesh and Actor Assets it's FBX Settings. + // Open the asset with the preferred asset editor, which for Mesh and Actor Assets it's Scene Settings. bool handled = false; AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Broadcast( &AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotifications::OpenAssetInAssociatedEditor, meshAsset.GetId(), handled); diff --git a/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRule.cpp b/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRule.cpp index d99797751e..9870dd1f96 100644 --- a/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRule.cpp +++ b/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRule.cpp @@ -19,7 +19,7 @@ namespace NvCloth namespace Pipeline { // It's necessary for the rule to specify the system allocator, otherwise - // the editor crashes when deleting the cloth modifier from FBX Settings. + // the editor crashes when deleting the cloth modifier from Scene Settings. AZ_CLASS_ALLOCATOR_IMPL(ClothRule, AZ::SystemAllocator, 0) const char* const ClothRule::DefaultChooseNodeName = "Choose a node"; diff --git a/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRuleBehavior.cpp b/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRuleBehavior.cpp index 15e3e34df0..c9df74ff61 100644 --- a/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRuleBehavior.cpp +++ b/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRuleBehavior.cpp @@ -61,7 +61,7 @@ namespace NvCloth [[maybe_unused]] const AZ::SceneAPI::Containers::Scene& scene, AZ::SceneAPI::DataTypes::IManifestObject& target) { - // When a cloth rule is created in the FBX Editor Settings... + // When a cloth rule is created in the Scene Settings... if (target.RTTI_IsTypeOf(ClothRule::TYPEINFO_Uuid())) { ClothRule* clothRule = azrtti_cast(&target); diff --git a/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRuleBehavior.h b/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRuleBehavior.h index 04dbc34eb1..eff6e8990d 100644 --- a/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRuleBehavior.h +++ b/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRuleBehavior.h @@ -39,7 +39,7 @@ namespace NvCloth //! It specifies the valid Scene Groups that are allowed to have //! cloth rules (aka cloth modifiers), these are Mesh and Actor groups. //! It also validates the cloth rules data for the manifest (asset containing - //! all the Scene information from the FBX Editor Settings). + //! all the Scene information from the Scene Settings). class ClothRuleBehavior : public AZ::SceneAPI::SceneCore::BehaviorComponent , public AZ::SceneAPI::Events::ManifestMetaInfoBus::Handler diff --git a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp index 0e476546ee..46598a13a4 100644 --- a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp @@ -56,7 +56,7 @@ namespace PhysX ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ->DataElement(AZ::Edit::UIHandlers::Default, &EditorProxyAssetShapeConfig::m_pxAsset, "PhysX Mesh", "PhysX mesh collider asset") ->Attribute(AZ_CRC_CE("EditButton"), "") - ->Attribute(AZ_CRC_CE("EditDescription"), "Open in FBX Settings") + ->Attribute(AZ_CRC_CE("EditDescription"), "Open in Scene Settings") ->DataElement(AZ::Edit::UIHandlers::Default, &EditorProxyAssetShapeConfig::m_configuration, "Configuration", "Configuration of asset shape") ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly); } diff --git a/Gems/PhysX/Code/Source/Pipeline/MeshAssetHandler.cpp b/Gems/PhysX/Code/Source/Pipeline/MeshAssetHandler.cpp index fcc07e2eed..a04b9327ac 100644 --- a/Gems/PhysX/Code/Source/Pipeline/MeshAssetHandler.cpp +++ b/Gems/PhysX/Code/Source/Pipeline/MeshAssetHandler.cpp @@ -165,7 +165,7 @@ namespace PhysX ; // Note: This class needs to have edit context reflection so PropertyAssetCtrl::OnEditButtonClicked - // can open the asset with the preferred asset editor (FBX Settings). + // can open the asset with the preferred asset editor (Scene Settings). if (auto* editContext = serializeContext->GetEditContext()) { editContext->Class("PhysX Mesh Asset", "") diff --git a/Gems/PhysX/Code/Source/Pipeline/MeshExporter.cpp b/Gems/PhysX/Code/Source/Pipeline/MeshExporter.cpp index f92b2d30e6..c2b80051fe 100644 --- a/Gems/PhysX/Code/Source/Pipeline/MeshExporter.cpp +++ b/Gems/PhysX/Code/Source/Pipeline/MeshExporter.cpp @@ -63,7 +63,7 @@ namespace PhysX } } pxDefaultErrorCallback; - // A struct to store the geometry data per FBX node + // A struct to store the geometry data per scene node struct NodeCollisionGeomExportData { AZStd::vector m_vertices; @@ -500,10 +500,10 @@ namespace PhysX assetData.m_materialNames = meshGroup.GetMaterialSlots(); assetData.m_physicsMaterialNames = meshGroup.GetPhysicsMaterials(); - // Updating materials lists from new materials gathered from fbx - // because this exporter runs when the FBX is being processed, which + // Updating materials lists from new materials gathered from the source scene file + // because this exporter runs when the source scene is being processed, which // could have a different content from when the mesh group info was - // entered in FBX Settings Editor. + // entered in Scene Settings Editor. if (!Utils::UpdateAssetPhysicsMaterials(assetMaterialsData.m_fbxMaterialNames, assetData.m_materialNames, assetData.m_physicsMaterialNames)) { return SceneEvents::ProcessingResult::Failure; diff --git a/Gems/PhysX/Code/Source/Pipeline/MeshExporter.h b/Gems/PhysX/Code/Source/Pipeline/MeshExporter.h index 8307e8289b..3bb6bea456 100644 --- a/Gems/PhysX/Code/Source/Pipeline/MeshExporter.h +++ b/Gems/PhysX/Code/Source/Pipeline/MeshExporter.h @@ -59,7 +59,7 @@ namespace PhysX //! A struct to store the materials of the mesh nodes selected in a mesh group. struct AssetMaterialsData { - //! Material names coming from FBX. + //! Material names coming from the source scene file. AZStd::vector m_fbxMaterialNames; //! Look-up table for fbxMaterialNames. diff --git a/Gems/SceneProcessing/Code/Include/Config/SceneProcessingConfigBus.h b/Gems/SceneProcessing/Code/Include/Config/SceneProcessingConfigBus.h index 24e36d6830..c6ebdd9870 100644 --- a/Gems/SceneProcessing/Code/Include/Config/SceneProcessingConfigBus.h +++ b/Gems/SceneProcessing/Code/Include/Config/SceneProcessingConfigBus.h @@ -70,7 +70,7 @@ namespace AZ * AddFileSoftName("_anim", PatternMatcher::MatchApproach::PostFix, "Ignore", false, * SceneAPI::DataTypes::IAnimationData::TYPEINFO_Name()) * If the filename ends with "_anim" this will mark all nodes as "Ignore" unless they're derived from IAnimationData. - * This will cause only animations to be exported from the .fbx file even if there's other data available. + * This will cause only animations to be exported from the source scene file even if there's other data available. */ virtual bool AddFileSoftName(const char* pattern, SceneAPI::SceneCore::PatternMatcher::MatchApproach approach, const char* virtualType, bool inclusive, const AZStd::string& graphObjectTypeName) = 0; diff --git a/Gems/SceneProcessing/Code/Source/Config/Components/SceneProcessingConfigSystemComponent.cpp b/Gems/SceneProcessing/Code/Source/Config/Components/SceneProcessingConfigSystemComponent.cpp index 6f1aab3e04..747253d5b1 100644 --- a/Gems/SceneProcessing/Code/Source/Config/Components/SceneProcessingConfigSystemComponent.cpp +++ b/Gems/SceneProcessing/Code/Source/Config/Components/SceneProcessingConfigSystemComponent.cpp @@ -42,7 +42,7 @@ namespace AZ m_softNames.push_back(aznew NodeSoftNameSetting("^.*_[Pp][Hh][Yy][Ss](_optimized)?$", PatternMatcher::MatchApproach::Regex, "PhysicsMesh", true)); m_softNames.push_back(aznew NodeSoftNameSetting("_ignore", PatternMatcher::MatchApproach::PostFix, "Ignore", false)); // If the filename ends with "_anim" this will mark all nodes as "Ignore" unless they're derived from IAnimationData. This will - // cause only animations to be exported from the .fbx file even if there's other data available. + // cause only animations to be exported from the source scene file even if there's other data available. m_softNames.push_back(aznew FileSoftNameSetting("_anim", PatternMatcher::MatchApproach::PostFix, "Ignore", false, { FileSoftNameSetting::GraphType(SceneAPI::DataTypes::IAnimationData::TYPEINFO_Name()) })); @@ -166,7 +166,7 @@ namespace AZ "Soft naming conventions", "Update the naming conventions to suit your project.") ->Attribute(AZ::Edit::Attributes::AutoExpand, false) ->DataElement(AZ::Edit::UIHandlers::Default, &SceneProcessingConfigSystemComponent::m_UseCustomNormals, - "Use Custom Normals", "When enabled, Open 3D Engine will use the DCC assets custom or tangent space normals. When disabled, the normals will be averaged. This setting can be overridden on individual FBX asset settings.") + "Use Custom Normals", "When enabled, Open 3D Engine will use the DCC assets custom or tangent space normals. When disabled, the normals will be averaged. This setting can be overridden on an individual scene file's asset settings.") ->Attribute(AZ::Edit::Attributes::AutoExpand, false); } } diff --git a/Gems/SceneProcessing/Code/Source/Generation/Components/TangentGenerator/TangentGenerateComponent.cpp b/Gems/SceneProcessing/Code/Source/Generation/Components/TangentGenerator/TangentGenerateComponent.cpp index 9ada34a270..e8798de0b6 100644 --- a/Gems/SceneProcessing/Code/Source/Generation/Components/TangentGenerator/TangentGenerateComponent.cpp +++ b/Gems/SceneProcessing/Code/Source/Generation/Components/TangentGenerator/TangentGenerateComponent.cpp @@ -107,7 +107,7 @@ namespace AZ::SceneGenerationComponents return AZ::SceneAPI::Events::ProcessingResult::Failure; } - // Now that we have the tangents and bitangents, calculate the tangent w values for the ones that we imported from Fbx, as they only have xyz. + // Now that we have the tangents and bitangents, calculate the tangent w values for the ones that we imported from the scene file, as they only have xyz. UpdateFbxTangentWValues(graph, nodeIndex, mesh); } @@ -122,7 +122,7 @@ namespace AZ::SceneGenerationComponents size_t uvSetIndex = 0; while (uvData) { - // Get the tangents and bitangents from Fbx. + // Get the tangents and bitangents from the source scene. AZ::SceneAPI::DataTypes::IMeshVertexTangentData* fbxTangentData = AZ::SceneAPI::SceneData::TangentsRule::FindTangentData(graph, nodeIndex, uvSetIndex, AZ::SceneAPI::DataTypes::TangentSpace::FromFbx); AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* fbxBitangentData = AZ::SceneAPI::SceneData::TangentsRule::FindBitangentData(graph, nodeIndex, uvSetIndex, AZ::SceneAPI::DataTypes::TangentSpace::FromFbx); @@ -197,7 +197,7 @@ namespace AZ::SceneGenerationComponents return true; // No fatal error } - // Check if we had tangents inside the Fbx file. + // Check if we had tangents inside the source scene file. AZ::SceneAPI::DataTypes::IMeshVertexTangentData* fbxTangentData = AZ::SceneAPI::SceneData::TangentsRule::FindTangentData(graph, nodeIndex, 0, AZ::SceneAPI::DataTypes::TangentSpace::FromFbx); AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* fbxBitangentData = AZ::SceneAPI::SceneData::TangentsRule::FindBitangentData(graph, nodeIndex, 0, AZ::SceneAPI::DataTypes::TangentSpace::FromFbx); @@ -211,7 +211,7 @@ namespace AZ::SceneGenerationComponents requiredSpaces.emplace_back(AZ::SceneAPI::DataTypes::TangentSpace::MikkT); } - // If all we need is import from FBX, and we have tangent data from Fbx already, then skip generating. + // If all we need is import from the source scene, and we have tangent data from the source scene already, then skip generating. if ((requiredSpaces.size() == 1 && requiredSpaces[0] == AZ::SceneAPI::DataTypes::TangentSpace::FromFbx) && fbxTangentData && fbxBitangentData) { return true; diff --git a/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderWorker.cpp b/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderWorker.cpp index 20c0dece37..6f1e54aa82 100644 --- a/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderWorker.cpp +++ b/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderWorker.cpp @@ -50,7 +50,7 @@ namespace SceneBuilder if (m_cachedFingerprint.empty()) { // put them in an ORDERED set so that changing the reflection - // or the gems loaded does not invalidate FBX files due to order of reflection changing. + // or the gems loaded does not invalidate scene files due to order of reflection changing. AZStd::set fragments; AZ::SerializeContext* context = nullptr; @@ -350,7 +350,7 @@ namespace SceneBuilder AZ::u32 SceneBuilderWorker::BuildSubId(const AZ::SceneAPI::Events::ExportProduct& product) const { // Instead of the just the lower 16-bits, use the full 32-bits that are available. There are production examples of - // uber-fbx files that contain hundreds of meshes that need to be split into individual mesh objects as an example. + // uber-scene files that contain hundreds of meshes that need to be split into individual mesh objects as an example. AZ::u32 id = static_cast(product.m_id.GetHash()); if (product.m_lod.has_value()) From f492949626d1f5a6af83480a2b9fb2c9ed0e9d95 Mon Sep 17 00:00:00 2001 From: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> Date: Thu, 1 Jul 2021 09:09:56 -0700 Subject: [PATCH 12/17] Removed mention of sample project from welcome screen (#1664) --- Code/Tools/ProjectManager/Source/ProjectsScreen.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Code/Tools/ProjectManager/Source/ProjectsScreen.cpp b/Code/Tools/ProjectManager/Source/ProjectsScreen.cpp index 9ea0b3ec2c..b1db77ea83 100644 --- a/Code/Tools/ProjectManager/Source/ProjectsScreen.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectsScreen.cpp @@ -92,8 +92,7 @@ namespace O3DE::ProjectManager QLabel* introLabel = new QLabel(this); introLabel->setObjectName("introLabel"); - introLabel->setText(tr("Welcome to O3DE! Start something new by creating a project. Not sure what to create? \nExplore what's " - "available by downloading our sample project.")); + introLabel->setText(tr("Welcome to O3DE! Start something new by creating a project.")); layout->addWidget(introLabel); QHBoxLayout* buttonLayout = new QHBoxLayout(); From ea42ef78b864943977c72a1f3eda19d6e1632af7 Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Thu, 1 Jul 2021 09:44:28 -0700 Subject: [PATCH 13/17] [LYN-4938] Prism: Paths in Engine settings page do not use consistent slashes (#1721) * Corrected focus for form line edit widgets. * Consistent slash usage for folder browse edit widgets. Signed-off-by: Benjamin Jillich --- .../ProjectManager/Source/FormBrowseEditWidget.cpp | 5 +++++ .../ProjectManager/Source/FormBrowseEditWidget.h | 1 + .../Source/FormFolderBrowseEditWidget.cpp | 11 +++++++++-- .../Source/FormFolderBrowseEditWidget.h | 2 ++ .../ProjectManager/Source/FormLineEditWidget.cpp | 10 ++++++++++ Code/Tools/ProjectManager/Source/FormLineEditWidget.h | 5 +++++ 6 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Code/Tools/ProjectManager/Source/FormBrowseEditWidget.cpp b/Code/Tools/ProjectManager/Source/FormBrowseEditWidget.cpp index be60638cbf..a81c65719c 100644 --- a/Code/Tools/ProjectManager/Source/FormBrowseEditWidget.cpp +++ b/Code/Tools/ProjectManager/Source/FormBrowseEditWidget.cpp @@ -21,4 +21,9 @@ namespace O3DE::ProjectManager connect(browseButton, &QPushButton::pressed, this, &FormBrowseEditWidget::HandleBrowseButton); m_frameLayout->addWidget(browseButton); } + + FormBrowseEditWidget::FormBrowseEditWidget(const QString& labelText, QWidget* parent) + : FormBrowseEditWidget(labelText, "", parent) + { + } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/FormBrowseEditWidget.h b/Code/Tools/ProjectManager/Source/FormBrowseEditWidget.h index 1d698c0052..26dbb43bba 100644 --- a/Code/Tools/ProjectManager/Source/FormBrowseEditWidget.h +++ b/Code/Tools/ProjectManager/Source/FormBrowseEditWidget.h @@ -20,6 +20,7 @@ namespace O3DE::ProjectManager public: explicit FormBrowseEditWidget(const QString& labelText, const QString& valueText = "", QWidget* parent = nullptr); + explicit FormBrowseEditWidget(const QString& labelText = "", QWidget* parent = nullptr); ~FormBrowseEditWidget() = default; protected slots: diff --git a/Code/Tools/ProjectManager/Source/FormFolderBrowseEditWidget.cpp b/Code/Tools/ProjectManager/Source/FormFolderBrowseEditWidget.cpp index 8053cfbfe6..1f3f1e34c1 100644 --- a/Code/Tools/ProjectManager/Source/FormFolderBrowseEditWidget.cpp +++ b/Code/Tools/ProjectManager/Source/FormFolderBrowseEditWidget.cpp @@ -15,8 +15,9 @@ namespace O3DE::ProjectManager { FormFolderBrowseEditWidget::FormFolderBrowseEditWidget(const QString& labelText, const QString& valueText, QWidget* parent) - : FormBrowseEditWidget(labelText, valueText, parent) + : FormBrowseEditWidget(labelText, parent) { + setText(valueText); } void FormFolderBrowseEditWidget::HandleBrowseButton() @@ -30,8 +31,14 @@ namespace O3DE::ProjectManager QString directory = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(this, tr("Browse"), defaultPath)); if (!directory.isEmpty()) { - m_lineEdit->setText(directory); + setText(directory); } } + + void FormFolderBrowseEditWidget::setText(const QString& text) + { + QString path = QDir::toNativeSeparators(text); + FormBrowseEditWidget::setText(path); + } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/FormFolderBrowseEditWidget.h b/Code/Tools/ProjectManager/Source/FormFolderBrowseEditWidget.h index 5ad3025c39..d8ef5edd4f 100644 --- a/Code/Tools/ProjectManager/Source/FormFolderBrowseEditWidget.h +++ b/Code/Tools/ProjectManager/Source/FormFolderBrowseEditWidget.h @@ -22,6 +22,8 @@ namespace O3DE::ProjectManager explicit FormFolderBrowseEditWidget(const QString& labelText, const QString& valueText = "", QWidget* parent = nullptr); ~FormFolderBrowseEditWidget() = default; + void setText(const QString& text) override; + protected: void HandleBrowseButton() override; }; diff --git a/Code/Tools/ProjectManager/Source/FormLineEditWidget.cpp b/Code/Tools/ProjectManager/Source/FormLineEditWidget.cpp index 25c76ddd6b..11932e6d5b 100644 --- a/Code/Tools/ProjectManager/Source/FormLineEditWidget.cpp +++ b/Code/Tools/ProjectManager/Source/FormLineEditWidget.cpp @@ -123,4 +123,14 @@ namespace O3DE::ProjectManager child->style()->polish(child); } } + + void FormLineEditWidget::setText(const QString& text) + { + m_lineEdit->setText(text); + } + + void FormLineEditWidget::mousePressEvent([[maybe_unused]] QMouseEvent* event) + { + m_lineEdit->setFocus(); + } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/FormLineEditWidget.h b/Code/Tools/ProjectManager/Source/FormLineEditWidget.h index 2d3802d6f6..cc8c0e3685 100644 --- a/Code/Tools/ProjectManager/Source/FormLineEditWidget.h +++ b/Code/Tools/ProjectManager/Source/FormLineEditWidget.h @@ -15,6 +15,7 @@ QT_FORWARD_DECLARE_CLASS(QLineEdit) QT_FORWARD_DECLARE_CLASS(QLabel) QT_FORWARD_DECLARE_CLASS(QFrame) QT_FORWARD_DECLARE_CLASS(QHBoxLayout) +QT_FORWARD_DECLARE_CLASS(QMouseEvent) namespace AzQtComponents { @@ -39,6 +40,8 @@ namespace O3DE::ProjectManager //! Returns a pointer to the underlying LineEdit. QLineEdit* lineEdit() const; + virtual void setText(const QString& text); + protected: QLabel* m_errorLabel = nullptr; QFrame* m_frame = nullptr; @@ -51,6 +54,8 @@ namespace O3DE::ProjectManager void onFocusOut(); private: + void mousePressEvent(QMouseEvent* event) override; + void refreshStyle(); }; } // namespace O3DE::ProjectManager From 74de7f785c4c9e3e0afbd78d193a432de47aefd1 Mon Sep 17 00:00:00 2001 From: amzn-hdoke <61443753+hdoke@users.noreply.github.com> Date: Thu, 1 Jul 2021 09:51:32 -0700 Subject: [PATCH 14/17] Fix reading AWSAttribution checkbox state (#1698) Signed-off-by: dhrudesh --- .../Source/Editor/Attribution/AWSCoreAttributionManager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp index 895ae4fec7..f2ff7ed816 100644 --- a/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp +++ b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp @@ -25,6 +25,7 @@ #include #include +#include namespace AWSCore @@ -170,7 +171,7 @@ namespace AWSCore switch (ret) { case QMessageBox::Save: - m_settingsRegistry->Set(AWSAttributionEnabledKey, msgBox->checkBox()); + m_settingsRegistry->Set(AWSAttributionEnabledKey, msgBox->checkBox()->checkState() == Qt::Checked); break; case QMessageBox::Cancel: default: From 1586c00fc8e630298fa2c601ee28fa28772e1486 Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Thu, 1 Jul 2021 09:53:17 -0700 Subject: [PATCH 15/17] [LYN-4929] Correct gems not showing as enabled for a template (#1722) * When there are multiple project templates present, we re-gather the gems when changing the selected the project template. * In case the user enabled or disabled any gem and they select a new project template, we show a warning dialog where users can either cancel the operation or proceed to the new project template. The warning dialog will only appear in case the enabled gems actually differ from the currently used template's default. * New helper function to select the used project template. * Storing the currently used project template index and only update the template details and emitting the changed event in case the user has actually chosen another template. This avoids emitting signals in case the user clicks on the already selected template. Signed-off-by: Benjamin Jillich --- .../Source/CreateProjectCtrl.cpp | 46 +++++++++++++++++-- .../ProjectManager/Source/CreateProjectCtrl.h | 1 + .../Source/GemCatalog/GemCatalogScreen.h | 2 + .../Source/NewProjectSettingsScreen.cpp | 41 +++++++++++++++-- .../Source/NewProjectSettingsScreen.h | 8 ++++ 5 files changed, 89 insertions(+), 9 deletions(-) diff --git a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp index 0ec395a6df..9c0b4726ed 100644 --- a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,40 @@ namespace O3DE::ProjectManager m_stack->addWidget(m_gemCatalogScreen); vLayout->addWidget(m_stack); + // When there are multiple project templates present, we re-gather the gems when changing the selected the project template. + connect(m_newProjectSettingsScreen, &NewProjectSettingsScreen::OnTemplateSelectionChanged, this, [=](int oldIndex, [[maybe_unused]] int newIndex) + { + const GemModel* gemModel = m_gemCatalogScreen->GetGemModel(); + const QVector toBeAdded = gemModel->GatherGemsToBeAdded(); + const QVector toBeRemoved = gemModel->GatherGemsToBeRemoved(); + if (!toBeAdded.isEmpty() || !toBeRemoved.isEmpty()) + { + // In case the user enabled or disabled any gem and the current selection does not match the default from the + // // project template anymore, we need to ask the user if they want to proceed as their modifications will be lost. + const QString title = tr("Modifications will be lost"); + const QString text = tr("You selected a new project template after modifying the enabled gems.\n\n" + "All modifications will be lost and the default from the new project template will be used.\n\n" + "Do you want to proceed?"); + if (QMessageBox::warning(this, title, text, QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) + { + // The users wants to proceed. Reinitialize based on the newly selected project template. + ReinitGemCatalogForSelectedTemplate(); + } + else + { + // Roll-back to the previously selected project template and + // block signals so that we don't end up in this same callback again. + m_newProjectSettingsScreen->SelectProjectTemplate(oldIndex, /*blockSignals=*/true); + } + } + else + { + // In case the user did not enable or disable any gem and the currently enabled gems matches the previously selected + // ones from the project template, we can just reinitialize based on the newly selected project template. + ReinitGemCatalogForSelectedTemplate(); + } + }); + QDialogButtonBox* buttons = new QDialogButtonBox(); buttons->setObjectName("footer"); vLayout->addWidget(buttons); @@ -81,10 +116,8 @@ namespace O3DE::ProjectManager currentScreen->NotifyCurrentScreen(); } - // Gather the gems from the project template. When we will have multiple project templates, we need to re-gather them - // on changing the template and let the user know that any further changes on top of the template will be lost. - QString projectTemplatePath = m_newProjectSettingsScreen->GetProjectTemplatePath(); - m_gemCatalogScreen->ReinitForProject(projectTemplatePath + "/Template", /*isNewProject=*/true); + // Gather the enabled gems from the default project template when starting the create new project workflow. + ReinitGemCatalogForSelectedTemplate(); } void CreateProjectCtrl::HandleBackButton() @@ -223,4 +256,9 @@ namespace O3DE::ProjectManager } } + void CreateProjectCtrl::ReinitGemCatalogForSelectedTemplate() + { + const QString projectTemplatePath = m_newProjectSettingsScreen->GetProjectTemplatePath(); + m_gemCatalogScreen->ReinitForProject(projectTemplatePath + "/Template", /*isNewProject=*/true); + } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.h b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.h index c2b4528802..c453e2d500 100644 --- a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.h +++ b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.h @@ -40,6 +40,7 @@ namespace O3DE::ProjectManager #ifdef TEMPLATE_GEM_CONFIGURATION_ENABLED void OnChangeScreenRequest(ProjectManagerScreen screen); void HandleSecondaryButton(); + void ReinitGemCatalogForSelectedTemplate(); #endif // TEMPLATE_GEM_CONFIGURATION_ENABLED private: diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h index 0fdfc6bdf5..b7fcf8446e 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h @@ -30,6 +30,8 @@ namespace O3DE::ProjectManager void ReinitForProject(const QString& projectPath, bool isNewProject); bool EnableDisableGemsForProject(const QString& projectPath); + GemModel* GetGemModel() const { return m_gemModel; } + private: void FillModel(const QString& projectPath, bool isNewProject); diff --git a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp index efecb2d901..26e5e074e5 100644 --- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp +++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp @@ -81,8 +81,14 @@ namespace O3DE::ProjectManager { if (button && button->property(k_templateIndexProperty).isValid()) { - int projectIndex = button->property(k_templateIndexProperty).toInt(); - UpdateTemplateDetails(m_templates.at(projectIndex)); + int projectTemplateIndex = button->property(k_templateIndexProperty).toInt(); + if (m_selectedTemplateIndex != projectTemplateIndex) + { + const int oldIndex = m_selectedTemplateIndex; + m_selectedTemplateIndex = projectTemplateIndex; + UpdateTemplateDetails(m_templates.at(m_selectedTemplateIndex)); + emit OnTemplateSelectionChanged(/*oldIndex=*/oldIndex, /*newIndex=*/m_selectedTemplateIndex); + } } }); @@ -115,7 +121,8 @@ namespace O3DE::ProjectManager flowLayout->addWidget(templateButton); } - m_projectTemplateButtonGroup->buttons().first()->setChecked(true); + // Select the first project template (default selection). + SelectProjectTemplate(0, /*blockSignals=*/true); } containerLayout->addWidget(templatesScrollArea); } @@ -159,8 +166,9 @@ namespace O3DE::ProjectManager QString NewProjectSettingsScreen::GetProjectTemplatePath() { - const int templateIndex = m_projectTemplateButtonGroup->checkedButton()->property(k_templateIndexProperty).toInt(); - return m_templates.at(templateIndex).m_path; + AZ_Assert(m_selectedTemplateIndex == m_projectTemplateButtonGroup->checkedButton()->property(k_templateIndexProperty).toInt(), + "Selected template index not in sync with the currently checked project template button."); + return m_templates.at(m_selectedTemplateIndex).m_path; } QFrame* NewProjectSettingsScreen::CreateTemplateDetails(int margin) @@ -216,4 +224,27 @@ namespace O3DE::ProjectManager m_templateSummary->setText(templateInfo.m_summary); m_templateIncludedGems->Update(templateInfo.m_includedGems); } + + void NewProjectSettingsScreen::SelectProjectTemplate(int index, bool blockSignals) + { + const QList buttons = m_projectTemplateButtonGroup->buttons(); + if (index >= buttons.size()) + { + return; + } + + if (blockSignals) + { + m_projectTemplateButtonGroup->blockSignals(true); + } + + QAbstractButton* button = buttons.at(index); + button->setChecked(true); + m_selectedTemplateIndex = button->property(k_templateIndexProperty).toInt(); + + if (blockSignals) + { + m_projectTemplateButtonGroup->blockSignals(false); + } + } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h index 4238ef98be..d812bfd091 100644 --- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h +++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h @@ -22,6 +22,8 @@ namespace O3DE::ProjectManager class NewProjectSettingsScreen : public ProjectSettingsScreen { + Q_OBJECT + public: explicit NewProjectSettingsScreen(QWidget* parent = nullptr); ~NewProjectSettingsScreen() = default; @@ -31,6 +33,11 @@ namespace O3DE::ProjectManager void NotifyCurrentScreen() override; + void SelectProjectTemplate(int index, bool blockSignals = false); + + signals: + void OnTemplateSelectionChanged(int oldIndex, int newIndex); + private: QString GetDefaultProjectPath(); QFrame* CreateTemplateDetails(int margin); @@ -41,6 +48,7 @@ namespace O3DE::ProjectManager QLabel* m_templateSummary; TagContainerWidget* m_templateIncludedGems; QVector m_templates; + int m_selectedTemplateIndex = -1; inline constexpr static int s_spacerSize = 20; inline constexpr static int s_templateDetailsContentMargin = 20; From af9f1aaae0257c41465823c37326dc898890f046 Mon Sep 17 00:00:00 2001 From: Shirang Jia Date: Thu, 1 Jul 2021 10:21:48 -0700 Subject: [PATCH 16/17] Remove unused package filelist (#1687) --- .../package/Platform/Windows/package_env.json | 23 --- .../Windows/package_filelists/atom.json | 162 ------------------ 2 files changed, 185 deletions(-) delete mode 100644 scripts/build/package/Platform/Windows/package_filelists/atom.json diff --git a/scripts/build/package/Platform/Windows/package_env.json b/scripts/build/package/Platform/Windows/package_env.json index 371bee18f6..970361bacc 100644 --- a/scripts/build/package/Platform/Windows/package_env.json +++ b/scripts/build/package/Platform/Windows/package_env.json @@ -30,29 +30,6 @@ "TYPE": "profile_vs2019" } ] - }, - "atom":{ - "PACKAGE_TARGETS":[ - { - "FILE_LIST": "atom.json", - "FILE_LIST_TYPE": "Windows", - "PACKAGE_NAME": "${PACKAGE_NAME_PATTERN}-windows-atom-${BUILD_NUMBER}.zip" - }, - { - "FILE_LIST": "symbols.json", - "FILE_LIST_TYPE": "All", - "PACKAGE_NAME": "${PACKAGE_NAME_PATTERN}-windows-atom-symbols-${BUILD_NUMBER}.zip" - } - ], - "BOOTSTRAP_CFG_GAME_FOLDER":"AtomSampleViewer;AtomTest", - "SKIP_BUILD": 1, - "BUILD_TARGETS":[ - { - "BUILD_CONFIG_FILENAME": "build_config.json", - "PLATFORM": "Windows", - "TYPE": "profile_vs2019_atom" - } - ] } } } diff --git a/scripts/build/package/Platform/Windows/package_filelists/atom.json b/scripts/build/package/Platform/Windows/package_filelists/atom.json deleted file mode 100644 index 7f049981a7..0000000000 --- a/scripts/build/package/Platform/Windows/package_filelists/atom.json +++ /dev/null @@ -1,162 +0,0 @@ -{ - "@lyengine": { - "**/*.pyc": "#exclude", - "*": "#include", - ".gitattributes": "#exclude", - ".gitignore": "#exclude", - ".gitmodules": "#exclude", - ".lfsconfig": "#exclude", - ".p4ignore": "#exclude", - ".submodules": "#exclude", - "AtomTest": - { - "**":"#include", - "**/*.ma":"#exclude", - "**/*.max":"#exclude", - "**/*.mb":"#exclude", - "**/*.psd":"#exclude" - }, - "AtomSampleViewer": - { - "**":"#include", - "**/*.ma":"#exclude", - "**/*.max":"#exclude", - "**/*.mb":"#exclude", - "**/*.psd":"#exclude" - }, - "cmake/**": "#include", - "Code": { - "Legacy/**": "#include", - "Framework/**": "#include", - "LauncherUnified/**": "#include", - "Editor/**": "#include", - "Tools": { - "Android/**": "#include", - "AWSNativeSDKInit/**": "#include", - "AssetProcessor*/**": "#include", - "AssetBundler/**": "#include", - "AzTestRunner/**": "#include", - "CrashHandler/**": "#include", - "DeltaCataloger/**": "#include", - "GridHub/**": "#include", - "News/**": "#include", - "PythonBindingsExample/**": "#include", - "RemoteConsole/**": "#include", - "SceneAPI/**": "#include", - "SerializeContextTools/**": "#include", - "CMakeLists.txt": "#include" - }, - "CMakeLists.txt": "#include" - }, - "ctest_scripts/**": "#include", - "Editor/**": "#include", - "Engine/**": "#include", - "Gems": { - "Achievements": "#include", - "AssetMemoryAnalyzer": "#include", - "AssetValidation": "#include", - "Atom": "#include", - "AtomLyIntegration": "#include", - "AudioEngineWwise": "#include", - "AudioSystem": "#include", - "AutomatedLauncherTesting": "#include", - "Blast": "#include", - "Camera": "#include", - "CameraFramework": "#include", - "CertificateManager": "#include", - "ChatPlay": "#include", - "Clouds": "#include", - "CrashReporting": "#include", - "CustomAssetExample": "#include", - "DebugDraw": "#include", - "EditorPythonBindings": "#include", - "EMotionFX": "#include", - "ExpressionEvaluation": "#include", - "FastNoise": "#include", - "GameEffectSystem": "#include", - "GameState": "#include", - "GameStateSamples": "#include", - "Gestures": "#include", - "GradientSignal": "#include", - "GraphCanvas": "#include", - "GraphModel": "#include", - "HttpRequestor": "#include", - "ImGui": "#include", - "InAppPurchases": "#include", - "LandscapeCanvas": "#include", - "LegacyTerrain": "#include", - "LmbrCentral": "#include", - "LocalUser": "#include", - "LyShine": "#include", - "LyShineExamples": "#include", - "Maestro": "#include", - "MessagePopup": "#include", - "Metastream": "#include", - "Microphone": "#include", - "Multiplayer": "#include", - "MultiplayerImGui": "#include", - "NvCloth": "#include", - "PhysX": "#include", - "PhysXDebug": "#include", - "Presence": "#include", - "QtForPython": "#include", - "RADTelemetry": "#include", - "RenderToTexture": "#include", - "SaveData": "#include", - "SceneLoggingExample": "#include", - "SceneProcessing": "#include", - "ScriptCanvas": "#include", - "ScriptCanvasDeveloper": "#include", - "ScriptCanvasDiagnosticLibrary": "#include", - "ScriptCanvasPhysics": "#include", - "ScriptCanvasTesting": "#include", - "ScriptedEntityTweener": "#include", - "ScriptEvents": "#include", - "SliceFavorites": "#include", - "StartingPointCamera": "#include", - "StartingPointInput": "#include", - "StartingPointMovement": "#include", - "Substance": "#include", - "SurfaceData": "#include", - "SVOGI": "#include", - "TestAssetBuilder": "#include", - "TextureAtlas": "#include", - "TickBusOrderViewer": "#include", - "TouchBending": "#include", - "Twitch": "#include", - "Vegetation": "#include", - "VideoPlayback": "#include", - "VideoPlaybackBink": "#include", - "VideoPlaybackFramework": "#include", - "VirtualGamepad": "#include", - "Visibility": "#include", - "Water": "#include", - "WhiteBox": "#include", - "CMakeLists.txt": "#include" - }, - "Tools": { - "3dsmax/**": "#include", - "7za.exe": "#include", - "7za_legal_notice.txt": "#include", - "PakShaders/**": "#include", - "Python/**": "#include", - "Redistributables": { - "**": "#include", - "ANGLE/**": "#exclude", - "D3DCompiler/**": "#exclude", - "DbgHelp/**": "#exclude", - "FFMpeg/**": "#exclude", - "LuaCompiler/**": "#exclude", - "MSVC90/**": "#exclude", - "OpenGL32/**": "#exclude", - "SSLEAY/**": "#exclude" - }, - "RemoteConsole/**": "#include", - "__init__.py": "#include", - "lmbr_aws/**": "#include", - "maxscript/**": "#include", - "maya/**": "#include", - "photoshop/**": "#include" - } - } -} \ No newline at end of file From d34d08819103a8ace0498e87f7a4485af3f4663f Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Thu, 1 Jul 2021 13:53:17 -0500 Subject: [PATCH 17/17] Miscellaneous prefab/converter bugfixes to support TrackView (#1701) This has a small bundle of bugfixes and improvements all based around improving prefab TrackView support: * JsonMerger - improved the error message when patch remove operations fail to make the specific failure more obvious Instance - swapped the order of destroying entities vs clearing the lookup tables so that lookups still produce valid results during destruction. (This could happen while creating undo caches) * InstanceEntityIdMapper - in the case where an id isn't found, it now returns an invalid id instead of an "attempted-valid" one that still generally turned out to be not-valid * PrefabUndo - downgraded a potential crash to an error message if for some reason the patch contains changes to an entity that doesn't currently have an alias. (This case can be caused occasionally by other bugs and error conditions) * EditorSequenceComponent - downgraded a potential crash to an assert for the times when it tries to remove components, fails, but thinks it succeeded. (This case can currently be caused by using Maestro with Prefabs enabled) * EditorSequenceAgentComponent - added an undo cache refresh whenever the component deletes itself, so that deleting itself during an EditorSequenceComponent destruction chain of events leaves the undo cache in the correct state. * SliceConverter - fixed the conversion of entity references in top-level slice instance entities that refer down to nested slice entities. There was a chicken-and-egg problem in terms of which entities need to be created first to make the references and the prefab patching & serialization happy. This was worked around by creating placeholder top-level entities, then the nested slice entities, then replacing the top-level entities with the fully-realized ones. Specific changes: * Added more informative error message. Signed-off-by: mbalfour (cherry picked from commit 672608a6c833c07295996cd9b3449825222b74d0) * Changed the error condition to produce a "valid" invalid id instead of a deterministic but not-valid id Signed-off-by: mbalfour (cherry picked from commit 3673950c949de8e067b32ddafaffd07e648a13d8) * Guard against invalid reference assert/crash Signed-off-by: mbalfour (cherry picked from commit 268d4ef3447f268a1372d07e028b9e67bac5c64e) * Downgrade an invalid reference crash to an assert Signed-off-by: mbalfour (cherry picked from commit 38c9303770845f4e863273dd6fb8fc7e83380425) * Improved logic for handling entity references across nested slices. Signed-off-by: mbalfour (cherry picked from commit 7e89a016d95fb72cb5f119e1e3768daa60e6bfb4) * Changed order of entities.clear() call so that instance lookups are still valid during entity destruction. Signed-off-by: mbalfour * Add undo cache notification when removing Maestro components. Signed-off-by: mbalfour --- .../AzCore/Serialization/Json/JsonMerger.cpp | 7 +- .../Prefab/Instance/Instance.cpp | 4 +- .../Instance/InstanceEntityIdMapper.cpp | 2 +- .../AzToolsFramework/Prefab/PrefabUndo.cpp | 10 +- .../SerializeContextTools/SliceConverter.cpp | 161 +++++++++++++----- .../EditorSequenceAgentComponent.cpp | 12 +- .../Components/EditorSequenceComponent.cpp | 26 ++- 7 files changed, 169 insertions(+), 53 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp index be20a46626..61869b7eb5 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp @@ -403,7 +403,12 @@ namespace AZ { if (!parentValue->EraseMember(tokens[path.GetTokenCount() - 1].name)) { - return settings.m_reporting(R"(The "remove" operation failed to remove member from object.)", + rapidjson::StringBuffer pathString; + path.Stringify(pathString); + return settings.m_reporting( + AZStd::string::format( + R"(The "remove" operation failed to remove member '%s' from object at path '%s'.)", + tokens[path.GetTokenCount() - 1].name, pathString.GetString()), ResultCode(Tasks::Merge, Outcomes::Invalid), element); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp index b229fb7f9d..1bacc11df3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp @@ -280,9 +280,11 @@ namespace AzToolsFramework } } + // Destroy the entities *before* clearing the lookup maps so that any lookups triggered during an entity's destructor + // are still valid. + m_entities.clear(); m_instanceToTemplateEntityIdMap.clear(); m_templateToInstanceEntityIdMap.clear(); - m_entities.clear(); } bool Instance::RegisterEntity(const AZ::EntityId& entityId, const EntityAlias& entityAlias) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceEntityIdMapper.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceEntityIdMapper.cpp index c000dd9349..33cbe67608 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceEntityIdMapper.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceEntityIdMapper.cpp @@ -157,7 +157,7 @@ namespace AzToolsFramework "Prefab - EntityIdMapper: Entity with Id %s has no registered owning instance", entityId.ToString().c_str()); - return AZStd::string::format("Entity_%s", entityId.ToString().c_str()); + return {}; } Instance* owningInstance = &(owningInstanceReference->get()); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp index fef43fbfcc..e29c33a21f 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp @@ -70,7 +70,15 @@ namespace AzToolsFramework "Failed to find an owning instance for the entity with id %llu.", static_cast(entityId)); Instance& instance = instanceReference->get(); m_templateId = instance.GetTemplateId(); - m_entityAlias = (instance.GetEntityAlias(entityId)).value(); + auto aliasReference = instance.GetEntityAlias(entityId); + if (!aliasReference.has_value()) + { + AZ_Error( + "Prefab", aliasReference.has_value(), "Failed to find the entity alias for entity %s.", entityId.ToString().c_str()); + return; + } + + m_entityAlias = aliasReference.value(); //generate undo/redo patches m_instanceToTemplateInterface->GeneratePatch(m_redoPatch, initialState, endState); diff --git a/Code/Tools/SerializeContextTools/SliceConverter.cpp b/Code/Tools/SerializeContextTools/SliceConverter.cpp index 5672f20543..0ffe7427e7 100644 --- a/Code/Tools/SerializeContextTools/SliceConverter.cpp +++ b/Code/Tools/SerializeContextTools/SliceConverter.cpp @@ -208,13 +208,6 @@ namespace AZ bool SliceConverter::ConvertSliceToPrefab( AZ::SerializeContext* serializeContext, AZ::IO::PathView outputPath, bool isDryRun, AZ::Entity* rootEntity) { - /* Given a root slice entity, we convert it to a prefab by doing the following: - * - Locate the SliceComponent - * - Take all the entities directly located on the slice, and put them into a prefab - * - Fix up any top-level entities to have the prefab container entity as their parent - * - If there are any nested slice instances, convert the nested slices to prefabs, then convert the instances. - */ - auto prefabSystemComponentInterface = AZ::Interface::Get(); // Find the slice from the root entity. @@ -233,23 +226,47 @@ namespace AZ sliceComponent->RemoveAllEntities(deleteEntities, removeEmptyInstances); AZ_Printf("Convert-Slice", " Slice contains %zu entities.\n", sliceEntities.size()); - // Create the Prefab with the entities from the slice. + // Create an empty Prefab as the start of our conversion. // The entities are added in a separate step so that we can give them deterministic entity aliases that match their entity Ids AZStd::unique_ptr sourceInstance( prefabSystemComponentInterface->CreatePrefab({}, {}, outputPath)); + + // Add entities into our prefab. + // In slice->prefab conversions, there's a chicken-and-egg problem that occurs with entity references, so we're initially + // going to add empty dummy entities with the right IDs and aliases. + // The problem is that we can have entities in this root list that have references to nested slice instance entities that we + // haven't created yet, and we will have nested slice entities that need to reference these entities as parents. + // If we create these entities as fully-formed first, they will fail to serialize correctly when adding each nested instance, + // due to the references not pointing to valid entities yet. And if we *wait* to create these and build the nested instances + // first, they'll fail to serialize correctly due to referencing these as parents. + // So our solution is that we'll initially create these entities as empty placeholders with no references, *then* we'll build + // up the nested instances, *then* we'll finish building these entities out. + + // prefabPlaceholderEntities will hold onto pointers to the entities we're building up in the prefab. The prefab will own + // the lifetime of them, but we'll use the references here for convenient access. + AZStd::vector prefabPlaceholderEntities; + // entityAliases will hold onto the alias we want to use for each of those entities. We'll need to use the same alias when + // we replace the entities at the end. + AZStd::vector entityAliases; for (auto& entity : sliceEntities) { - sourceInstance->AddEntity(*entity, AZStd::string::format("Entity_%s", entity->GetId().ToString().c_str())); + auto id = entity->GetId(); + prefabPlaceholderEntities.emplace_back(aznew AZ::Entity(id)); + entityAliases.emplace_back(AZStd::string::format("Entity_%s", id.ToString().c_str())); + sourceInstance->AddEntity(*(prefabPlaceholderEntities.back()), entityAliases.back()); + + // Save off a mapping of the original slice entity IDs to the new prefab template entity aliases. + // We'll need this mapping for fixing up all the entity references in this slice as well as any nested instances. + auto result = m_aliasIdMapper.emplace(id, SliceEntityMappingInfo(sourceInstance->GetTemplateId(), entityAliases.back())); + if (!result.second) + { + AZ_Printf("Convert-Slice", " Duplicate entity alias -> entity id entries found, conversion may not be successful.\n"); + } } // Dispatch events here, because prefab creation might trigger asset loads in rare circumstances. AZ::Data::AssetManager::Instance().DispatchEvents(); - // Fix up the container entity to have the proper components and fix up the slice entities to have the proper hierarchy - // with the container as the top-most parent. - AzToolsFramework::Prefab::EntityOptionalReference container = sourceInstance->GetContainerEntity(); - FixPrefabEntities(container->get(), sliceEntities); - // Keep track of the template Id we created, we're going to remove it at the end of slice file conversion to make sure // the data doesn't stick around between file conversions. auto templateId = sourceInstance->GetTemplateId(); @@ -260,26 +277,8 @@ namespace AZ } m_createdTemplateIds.emplace(templateId); - // Save off a mapping of the original slice entity IDs to the new prefab template entity aliases. - // When converting nested slices, this mapping will be needed to fix up the parent entity hierarchy correctly. - auto entityAliases = sourceInstance->GetEntityAliases(); - for (auto& alias : entityAliases) - { - auto id = sourceInstance->GetEntityId(alias); - auto result = m_aliasIdMapper.emplace(id, SliceEntityMappingInfo(templateId, alias)); - if (!result.second) - { - AZ_Printf("Convert-Slice", " Duplicate entity alias -> entity id entries found, conversion may not be successful.\n"); - } - } - - // Save off a mapping of the slice's metadata entity ID as well, even though we never converted the entity itself. - // This will help us better detect entity ID mapping errors for nested slice instances. - AZ::Entity* metadataEntity = sliceComponent->GetMetadataEntity(); - constexpr bool isMetadataEntity = true; - m_aliasIdMapper.emplace(metadataEntity->GetId(), SliceEntityMappingInfo(templateId, "MetadataEntity", isMetadataEntity)); - - // Update the prefab template with the fixed-up data in our prefab instance. + // Save off the the first version of this prefab template with our empty placeholder entities. + // As it saves off, the entities will all change IDs during serialization / propagation, but the aliases will remain the same. AzToolsFramework::Prefab::PrefabDom prefabDom; bool storeResult = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*sourceInstance, prefabDom); if (storeResult == false) @@ -288,10 +287,20 @@ namespace AZ return false; } prefabSystemComponentInterface->UpdatePrefabTemplate(templateId, prefabDom); + AZ::Interface::Get()->UpdateTemplateInstancesInQueue(); // Dispatch events here, because prefab serialization might trigger asset loads in rare circumstances. AZ::Data::AssetManager::Instance().DispatchEvents(); + // Save off a mapping of the slice's metadata entity ID as well, even though we never converted the entity itself. + // This will help us better detect entity ID mapping errors for nested slice instances. + AZ::Entity* metadataEntity = sliceComponent->GetMetadataEntity(); + constexpr bool isMetadataEntity = true; + m_aliasIdMapper.emplace(metadataEntity->GetId(), SliceEntityMappingInfo(templateId, "MetadataEntity", isMetadataEntity)); + + // Also save off a mapping of the prefab's container entity ID. + m_aliasIdMapper.emplace(sourceInstance->GetContainerEntityId(), SliceEntityMappingInfo(templateId, "ContainerEntity")); + // If this slice has nested slices, we need to loop through those, convert them to prefabs as well, and // set up the new nesting relationships correctly. const SliceComponent::SliceList& sliceList = sliceComponent->GetSlices(); @@ -305,6 +314,51 @@ namespace AZ } } + // *After* converting the nested slices, remove our placeholder entities and replace them with the correct ones. + // The placeholder entity IDs will have changed from what we originally created, so we need to make sure our replacement + // entities have the same IDs and aliases as the placeholders so that any instance references that have already been fixed + // up continue to reference the correct entities here. + for (size_t curEntityIdx = 0; curEntityIdx < sliceEntities.size(); curEntityIdx++) + { + auto& sliceEntity = sliceEntities[curEntityIdx]; + auto& prefabEntity = prefabPlaceholderEntities[curEntityIdx]; + sliceEntity->SetId(prefabEntity->GetId()); + } + // Remove and delete our placeholder entities. + // (By using an empty callback on DetachEntities, the unique_ptr will auto-delete the placeholder entities) + sourceInstance->DetachEntities([](AZStd::unique_ptr){}); + prefabPlaceholderEntities.clear(); + for (size_t curEntityIdx = 0; curEntityIdx < sliceEntities.size(); curEntityIdx++) + { + sourceInstance->AddEntity(*(sliceEntities[curEntityIdx]), entityAliases[curEntityIdx]); + } + + // Fix up the container entity to have the proper components and fix up the slice entities to have the proper hierarchy + // with the container as the top-most parent. + AzToolsFramework::Prefab::EntityOptionalReference container = sourceInstance->GetContainerEntity(); + FixPrefabEntities(container->get(), sliceEntities); + + // Also save off a mapping of the prefab's container entity ID. + m_aliasIdMapper.emplace(sourceInstance->GetContainerEntityId(), SliceEntityMappingInfo(templateId, "ContainerEntity")); + + // Remap all of the entity references that exist in these top-level slice entities. + SliceComponent::InstantiatedContainer instantiatedEntities(false); + instantiatedEntities.m_entities = sliceEntities; + RemapIdReferences(m_aliasIdMapper, sourceInstance.get(), sourceInstance.get(), &instantiatedEntities, serializeContext); + + // Finally, store the completed slice->prefab conversion back into the template. + storeResult = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*sourceInstance, prefabDom); + if (storeResult == false) + { + AZ_Printf("Convert-Slice", " Failed to convert prefab instance data to a PrefabDom.\n"); + return false; + } + prefabSystemComponentInterface->UpdatePrefabTemplate(templateId, prefabDom); + AZ::Interface::Get()->UpdateTemplateInstancesInQueue(); + + // Dispatch events here, because prefab serialization might trigger asset loads in rare circumstances. + AZ::Data::AssetManager::Instance().DispatchEvents(); + if (isDryRun) { PrintPrefab(templateId); @@ -417,7 +471,7 @@ namespace AZ auto instances = slice.GetInstances(); AZ_Printf( - "Convert-Slice", " Attaching %zu instances of nested slice '%s'.\n", instances.size(), + "Convert-Slice", "Attaching %zu instances of nested slice '%s'.\n", instances.size(), nestedPrefabPath.Native().c_str()); // Before processing any further, save off all the known entity IDs from all the instances and how they map back to @@ -435,14 +489,20 @@ namespace AZ } // Now that we have all the entity ID mappings, convert all the instances. + size_t curInstance = 0; for (auto& instance : instances) { + AZ_Printf("Convert-Slice", " Converting instance %zu.\n", curInstance++); bool instanceConvertResult = ConvertSliceInstance(instance, sliceAsset, nestedTemplate, sourceInstance); if (!instanceConvertResult) { return false; } } + + AZ_Printf( + "Convert-Slice", "Finished attaching %zu instances of nested slice '%s'.\n", instances.size(), + nestedPrefabPath.Native().c_str()); } return true; @@ -507,6 +567,10 @@ namespace AZ return false; } + // Save off a mapping of the new nested Instance's container ID + m_aliasIdMapper.emplace(nestedInstance->GetContainerEntityId(), + SliceEntityMappingInfo(nestedInstance->GetTemplateId(), "ContainerEntity")); + // Get the DOM for the unmodified nested instance. This will be used later below for generating the correct patch // to the top-level template DOM. AzToolsFramework::Prefab::PrefabDom unmodifiedNestedInstanceDom; @@ -595,7 +659,7 @@ namespace AZ auto parentId = transformComponent->GetParentId(); if (parentId.IsValid()) { - // Look to see if the parent ID exists in the same instance (i.e. an entity in the nested slice is a + // Look to see if the parent ID exists in a different instance (i.e. an entity in the nested slice is a // child of an entity in the containing slice). If this case exists, we need to adjust the parents so that // the child entity connects to the prefab container, and the *container* is the child of the entity in the // containing slice. (i.e. go from A->B to A->container->B) @@ -607,6 +671,7 @@ namespace AZ { if (topLevelInstance->GetTemplateId() == parentMappingInfo.m_templateId) { + // This entity has a parent from the topLevelInstance, so get its parent ID. parentId = topLevelInstance->GetEntityId(parentMappingInfo.m_entityAlias); } else @@ -630,15 +695,23 @@ namespace AZ } // Set the container's parent to this entity's parent, and set this entity's parent to the container - // auto newParentId = topLevelInstance->GetEntityId(parentMappingInfo.m_entityAlias); SetParentEntity(containerEntity->get(), parentId, false); onlySetIfInvalid = false; } + else + { + // If the parent ID is valid and exists inside the same slice instance (i.e. template IDs are equal) + // then it's just a nested entity hierarchy inside the slice and we don't need to adjust anything. + // "onlySetIfInvalid" will still be true, which means we won't change the parent ID below. + } + } + else + { + // If the parent ID is set to something valid, but we can't find it in our ID mapper, something went wrong. + // We'll assert, but don't change the container entity's parent below. + AZ_Assert(false, "Could not find parent entity id: %s", parentId.ToString().c_str()); } - // If the parent ID is valid, but NOT in the top-level instance, then it's just a nested hierarchy inside - // the slice and we don't need to adjust anything. "onlySetIfInvalid" will still be true, which means we - // won't change the parent ID below. } SetParentEntity(*entity, containerEntityId, onlySetIfInvalid); @@ -846,9 +919,10 @@ namespace AZ { auto entityEntry = idMapper.find(sourceId); - // Since we've already remapped transform hierarchies to include container entities, it's possible that our entity - // reference is pointing to a container, which means it won't be in our slice mapping table. In that case, just - // return it as-is. + // The id mapping table should include all of our known slice entities, slice metadata entities, and prefab + // container entities. If we can't find the entity reference, it should either be because it's actually invalid + // in the source data or because it's a transform parent id that we've already remapped prior to this point. + // Either way, just keep it as-is and return it. if (entityEntry == idMapper.end()) { return sourceId; @@ -876,6 +950,7 @@ namespace AZ else { AZ_Error("Convert-Slice", false, " Couldn't find source ID %s", sourceId.ToString().c_str()); + newId = sourceId; } } else diff --git a/Gems/Maestro/Code/Source/Components/EditorSequenceAgentComponent.cpp b/Gems/Maestro/Code/Source/Components/EditorSequenceAgentComponent.cpp index dceeac3238..f80c1edb81 100644 --- a/Gems/Maestro/Code/Source/Components/EditorSequenceAgentComponent.cpp +++ b/Gems/Maestro/Code/Source/Components/EditorSequenceAgentComponent.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace Maestro { @@ -161,9 +162,18 @@ namespace Maestro return; } + AZ::EntityId curEntityId = GetEntityId(); + // remove this SequenceAgent from this entity if no sequenceComponents are connected to it AzToolsFramework::EntityCompositionRequestBus::Broadcast(&AzToolsFramework::EntityCompositionRequests::RemoveComponents, AZ::Entity::ComponentArrayType{this}); - + + // Let any currently-active undo operations know that this entity has changed state. + auto undoCacheInterface = AZ::Interface::Get(); + if (undoCacheInterface) + { + undoCacheInterface->UpdateCache(curEntityId); + } + // CAUTION! // THIS CLASS INSTANCE IS NOW DEAD DUE TO DELETION BY THE ENTITY DURING RemoveComponents! } diff --git a/Gems/Maestro/Code/Source/Components/EditorSequenceComponent.cpp b/Gems/Maestro/Code/Source/Components/EditorSequenceComponent.cpp index e62d801cf6..acb8b78067 100644 --- a/Gems/Maestro/Code/Source/Components/EditorSequenceComponent.cpp +++ b/Gems/Maestro/Code/Source/Components/EditorSequenceComponent.cpp @@ -205,15 +205,31 @@ namespace Maestro if (addComponentResult.IsSuccess()) { - // We need to register our Entity and Component Ids with the SequenceAgentComponent so we can communicate over EBuses with it. - // We can't do this registration over an EBus because we haven't registered with it yet - do it with pointers? Is this safe? - agentComponent = static_cast(addComponentResult.GetValue()[entityToAnimate].m_componentsAdded[0]); + if (!addComponentResult.GetValue()[entityToAnimate].m_componentsAdded.empty()) + { + // We need to register our Entity and Component Ids with the SequenceAgentComponent so we can communicate over EBuses + // with it. We can't do this registration over an EBus because we haven't registered with it yet - do it with pointers? + // Is this safe? + agentComponent = static_cast( + addComponentResult.GetValue()[entityToAnimate].m_componentsAdded[0]); + } + else + { + AZ_Assert( + !addComponentResult.GetValue()[entityToAnimate].m_componentsAdded.empty(), + "Add component result was successful, but the EditorSequenceAgentComponent wasn't added. " + "This can happen if the entity id isn't found for some reason: entity id = %s", + entityToAnimate.ToString().c_str()); + } } } - AZ_Assert(agentComponent, "EditorSequenceComponent::AddEntityToAnimate unable to create or find sequenceAgentComponent.") + AZ_Assert(agentComponent, "EditorSequenceComponent::AddEntityToAnimate unable to create or find sequenceAgentComponent."); // Notify the SequenceAgentComponent that we're connected to it - after this call, all communication with the Agent is over an EBus - agentComponent->ConnectSequence(GetEntityId()); + if (agentComponent) + { + agentComponent->ConnectSequence(GetEntityId()); + } } ///////////////////////////////////////////////////////////////////////////////////////////////////////