diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/CMakeLists.txt b/Gems/AtomLyIntegration/EMotionFXAtom/Code/CMakeLists.txt index 5a08bab4fa..cc71e4f237 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/CMakeLists.txt +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/CMakeLists.txt @@ -54,11 +54,21 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) INCLUDE_DIRECTORIES PRIVATE Source + Tools BUILD_DEPENDENCIES PRIVATE AZ::AzCore Gem::EMotionFX_Atom.Static + Gem::EMotionFX.Editor.Static + Gem::AtomToolsFramework.Static + Gem::AtomToolsFramework.Editor + Gem::Atom_Component_DebugCamera.Static + Gem::Atom_Feature_Common.Static + Gem::AtomLyIntegration_CommonFeatures.Static RUNTIME_DEPENDENCIES Gem::EMotionFX.Editor + COMPILE_DEFINITIONS + PUBLIC + EMOTIONFXATOM_EDITOR ) endif() diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorModule.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorModule.cpp index 49c2e52c1a..93481c1da6 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorModule.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorModule.cpp @@ -11,6 +11,9 @@ #include #include #include +#ifdef EMOTIONFXATOM_EDITOR +#include +#endif namespace AZ { @@ -28,7 +31,10 @@ namespace AZ : Module() { m_descriptors.insert(m_descriptors.end(), { - ActorSystemComponent::CreateDescriptor() + ActorSystemComponent::CreateDescriptor(), +#ifdef EMOTIONFXATOM_EDITOR + EMotionFXAtom::EditorSystemComponent::CreateDescriptor(), +#endif }); } @@ -39,6 +45,9 @@ namespace AZ { return ComponentTypeList{ azrtti_typeid(), +#ifdef EMOTIONFXATOM_EDITOR + azrtti_typeid(), +#endif }; } }; diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/Editor/EditorSystemComponent.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/Editor/EditorSystemComponent.cpp new file mode 100644 index 0000000000..edd2f074fe --- /dev/null +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/Editor/EditorSystemComponent.cpp @@ -0,0 +1,39 @@ +/* + * 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 + * + */ + +#include +#include + +#include + +namespace AZ::EMotionFXAtom +{ + void EditorSystemComponent::Reflect(ReflectContext* context) + { + if (SerializeContext* serialize = azrtti_cast(context)) + { + serialize->Class()->Version(0); + } + } + + void EditorSystemComponent::Activate() + { + EMotionFX::Integration::SystemNotificationBus::Handler::BusConnect(); + } + + void EditorSystemComponent::Deactivate() + { + EMotionFX::Integration::SystemNotificationBus::Handler::BusDisconnect(); + } + + void EditorSystemComponent::OnRegisterPlugin() + { + EMStudio::PluginManager* pluginManager = EMStudio::EMStudioManager::GetInstance()->GetPluginManager(); + pluginManager->RegisterPlugin(aznew EMStudio::AtomRenderPlugin()); + } +} // namespace AZ::EMotionFXAtom diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/Editor/EditorSystemComponent.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/Editor/EditorSystemComponent.h new file mode 100644 index 0000000000..80ff7b0b8d --- /dev/null +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/Editor/EditorSystemComponent.h @@ -0,0 +1,32 @@ +/* + * 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 + * + */ +#pragma once + +#include +#include + +namespace AZ::EMotionFXAtom +{ + class EditorSystemComponent + : public Component + , private EMotionFX::Integration::SystemNotificationBus::Handler + { + public: + AZ_COMPONENT(EditorSystemComponent, "{1FAEC046-255D-4664-8F12-D16503C34431}"); + + static void Reflect(ReflectContext* context); + + protected: + // AZ::Component overrides + void Activate() override; + void Deactivate() override; + + // SystemNotificationBus::OnRegisterPlugin + void OnRegisterPlugin() override; + }; +} // namespace AZ::EMotionFXAtom diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp new file mode 100644 index 0000000000..ab54b1fa38 --- /dev/null +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp @@ -0,0 +1,293 @@ +/* + * 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 + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +namespace EMStudio +{ + static constexpr float DepthNear = 0.01f; + + AnimViewportRenderer::AnimViewportRenderer(AZ::RPI::ViewportContextPtr viewportContext) + : m_windowContext(viewportContext->GetWindowContext()) + { + // Create a new entity context + m_entityContext = AZStd::make_unique(); + m_entityContext->InitContext(); + + // Create the scene + auto sceneSystem = AzFramework::SceneSystemInterface::Get(); + AZ_Assert(sceneSystem, "Unable to retrieve scene system."); + AZ::Outcome, AZStd::string> createSceneOutcome = sceneSystem->CreateScene("AnimViewport"); + AZ_Assert(createSceneOutcome, "%s", createSceneOutcome.GetError().data()); + m_frameworkScene = createSceneOutcome.TakeValue(); + m_frameworkScene->SetSubsystem(m_entityContext.get()); + + // Create and register a scene with all available feature processors + AZ::RPI::SceneDescriptor sceneDesc; + m_scene = AZ::RPI::Scene::CreateScene(sceneDesc); + m_scene->EnableAllFeatureProcessors(); + + // Link our RPI::Scene to the AzFramework::Scene + m_frameworkScene->SetSubsystem(m_scene); + + // Create a render pipeline from the specified asset for the window context and add the pipeline to the scene + AZStd::string defaultPipelineAssetPath = "passes/MainRenderPipeline.azasset"; + AZ::Data::Asset pipelineAsset = AZ::RPI::AssetUtils::LoadAssetByProductPath( + defaultPipelineAssetPath.c_str(), AZ::RPI::AssetUtils::TraceLevel::Error); + m_renderPipeline = AZ::RPI::RenderPipeline::CreateRenderPipelineForWindow(pipelineAsset, *m_windowContext.get()); + pipelineAsset.Release(); + m_scene->AddRenderPipeline(m_renderPipeline); + m_renderPipeline->SetDefaultView(viewportContext->GetDefaultView()); + + // Currently the scene has to be activated after render pipeline was added so some feature processors (i.e. imgui) can be + // initialized properly with pipeline's pass information. + m_scene->Activate(); + AZ::RPI::RPISystemInterface::Get()->RegisterScene(m_scene); + AzFramework::EntityContextId entityContextId = m_entityContext->GetContextId(); + + // Get the FeatureProcessors + m_meshFeatureProcessor = m_scene->GetFeatureProcessor(); + + // Configure tone mapper + AzFramework::EntityContextRequestBus::EventResult( + m_postProcessEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "postProcessEntity"); + AZ_Assert(m_postProcessEntity != nullptr, "Failed to create post process entity."); + + m_postProcessEntity->CreateComponent(AZ::Render::PostFxLayerComponentTypeId); + m_postProcessEntity->CreateComponent(AZ::Render::ExposureControlComponentTypeId); + m_postProcessEntity->CreateComponent(azrtti_typeid()); + m_postProcessEntity->Activate(); + + // Init directional light processor + m_directionalLightFeatureProcessor = m_scene->GetFeatureProcessor(); + + // Init display mapper processor + m_displayMapperFeatureProcessor = m_scene->GetFeatureProcessor(); + + // Init Skybox + m_skyboxFeatureProcessor = m_scene->GetFeatureProcessor(); + m_skyboxFeatureProcessor->Enable(true); + m_skyboxFeatureProcessor->SetSkyboxMode(AZ::Render::SkyBoxMode::Cubemap); + + // Create IBL + AzFramework::EntityContextRequestBus::EventResult( + m_iblEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "IblEntity"); + AZ_Assert(m_iblEntity != nullptr, "Failed to create ibl entity."); + + m_iblEntity->CreateComponent(AZ::Render::ImageBasedLightComponentTypeId); + m_iblEntity->CreateComponent(azrtti_typeid()); + m_iblEntity->Activate(); + + // Load light preset + AZ::Data::Asset lightingPresetAsset = AZ::RPI::AssetUtils::LoadAssetByProductPath( + "lightingpresets/default.lightingpreset.azasset", AZ::RPI::AssetUtils::TraceLevel::Warning); + const AZ::Render::LightingPreset* preset = lightingPresetAsset->GetDataAs(); + SetLightingPreset(preset); + + // Create grid + AzFramework::EntityContextRequestBus::EventResult( + m_gridEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "ViewportGrid"); + AZ_Assert(m_gridEntity != nullptr, "Failed to create grid entity."); + + AZ::Render::GridComponentConfig gridConfig; + gridConfig.m_gridSize = 4.0f; + gridConfig.m_axisColor = AZ::Color(0.5f, 0.5f, 0.5f, 1.0f); + gridConfig.m_primaryColor = AZ::Color(0.3f, 0.3f, 0.3f, 1.0f); + gridConfig.m_secondaryColor = AZ::Color(0.5f, 0.1f, 0.1f, 1.0f); + auto gridComponent = m_gridEntity->CreateComponent(AZ::Render::GridComponentTypeId); + gridComponent->SetConfiguration(gridConfig); + + m_gridEntity->CreateComponent(azrtti_typeid()); + m_gridEntity->Activate(); + + Reinit(); + } + + AnimViewportRenderer::~AnimViewportRenderer() + { + // Destroy all the entity we created. + m_entityContext->DestroyEntity(m_iblEntity); + m_entityContext->DestroyEntity(m_postProcessEntity); + m_entityContext->DestroyEntity(m_gridEntity); + for (AZ::Entity* entity : m_actorEntities) + { + m_entityContext->DestroyEntity(entity); + } + m_actorEntities.clear(); + m_entityContext->DestroyContext(); + + for (AZ::Render::DirectionalLightFeatureProcessorInterface::LightHandle& handle : m_lightHandles) + { + m_directionalLightFeatureProcessor->ReleaseLight(handle); + } + m_lightHandles.clear(); + + m_frameworkScene->UnsetSubsystem(m_scene); + + auto sceneSystem = AzFramework::SceneSystemInterface::Get(); + AZ_Assert(sceneSystem, "AtomViewportRenderer was unable to get the scene system during destruction."); + bool removeSuccess = sceneSystem->RemoveScene("AnimViewport"); + if (!removeSuccess) + { + AZ_Assert(false, "AtomViewportRenderer should be removed."); + } + + AZ::RPI::RPISystemInterface::Get()->UnregisterScene(m_scene); + m_scene = nullptr; + } + + void AnimViewportRenderer::Reinit() + { + ReinitActorEntities(); + ResetEnvironment(); + } + + void AnimViewportRenderer::ResetEnvironment() + { + // Reset environment + AZ::Transform iblTransform = AZ::Transform::CreateIdentity(); + AZ::TransformBus::Event(m_iblEntity->GetId(), &AZ::TransformBus::Events::SetLocalTM, iblTransform); + + const AZ::Matrix4x4 rotationMatrix = AZ::Matrix4x4::CreateIdentity(); + AZ::RPI::ScenePtr scene = AZ::RPI::RPISystemInterface::Get()->GetDefaultScene(); + auto skyBoxFeatureProcessorInterface = scene->GetFeatureProcessor(); + skyBoxFeatureProcessorInterface->SetCubemapRotationMatrix(rotationMatrix); + } + + void AnimViewportRenderer::ReinitActorEntities() + { + // 1. Destroy all the entities that do not point to any actorAsset anymore. + AZStd::set assetLookup; + AzFramework::EntityContext* entityContext = m_entityContext.get(); + const size_t numActors = EMotionFX::GetActorManager().GetNumActors(); + for (size_t i = 0; i < numActors; ++i) + { + assetLookup.emplace(EMotionFX::GetActorManager().GetActorAsset(i).GetId()); + } + m_actorEntities.erase( + AZStd::remove_if( + m_actorEntities.begin(), m_actorEntities.end(), + [&assetLookup, entityContext](AZ::Entity* entity) + { + EMotionFX::Integration::ActorComponent* actorComponent = + entity->FindComponent(); + if (assetLookup.find(actorComponent->GetActorAsset().GetId()) == assetLookup.end()) + { + entityContext->DestroyEntity(entity); + return true; + } + return false; + }), + m_actorEntities.end()); + + // 2. Create an entity for every actorAsset stored in actor manager. + for (size_t i = 0; i < numActors; ++i) + { + AZ::Data::Asset actorAsset = EMotionFX::GetActorManager().GetActorAsset(i); + if (!actorAsset->IsReady()) + { + continue; + } + + AZ::Entity* entity = FindActorEntity(actorAsset); + if (!entity) + { + m_actorEntities.emplace_back(CreateActorEntity(actorAsset)); + } + } + } + + AZ::Entity* AnimViewportRenderer::FindActorEntity(AZ::Data::Asset actorAsset) const + { + const auto foundEntity = AZStd::find_if( + begin(m_actorEntities), end(m_actorEntities), + [match = actorAsset](const AZ::Entity* entity) + { + EMotionFX::Integration::ActorComponent* actorComponent = entity->FindComponent(); + return actorComponent->GetActorAsset() == match; + }); + return foundEntity != end(m_actorEntities) ? (*foundEntity) : nullptr; + } + + AZ::Entity* AnimViewportRenderer::CreateActorEntity(AZ::Data::Asset actorAsset) + { + AZ::Entity* actorEntity = m_entityContext->CreateEntity(actorAsset->GetActor()->GetName()); + actorEntity->CreateComponent(azrtti_typeid()); + actorEntity->CreateComponent(AZ::Render::MaterialComponentTypeId); + actorEntity->CreateComponent(azrtti_typeid()); + actorEntity->Activate(); + + EMotionFX::Integration::ActorComponent* actorComponent = actorEntity->FindComponent(); + actorComponent->SetActorAsset(actorAsset); + + // Since this entity belongs to the animation editor, we need to set the isOwnByRuntime flag to false. + actorComponent->GetActorInstance()->SetIsOwnedByRuntime(false); + // Selet the actor instance in the command manager after it has been created. + AZStd::string outResult; + EMStudioManager::GetInstance()->GetCommandManager()->ExecuteCommandInsideCommand( + AZStd::string::format("Select -actorInstanceID %i", actorComponent->GetActorInstance()->GetID()).c_str(), outResult); + + return actorEntity; + } + + void AnimViewportRenderer::SetLightingPreset(const AZ::Render::LightingPreset* preset) + { + if (!preset) + { + AZ_Warning("AnimViewportRenderer", false, "Attempting to set invalid lighting preset."); + return; + } + + AZ::Render::ImageBasedLightFeatureProcessorInterface* iblFeatureProcessor = + m_scene->GetFeatureProcessor(); + AZ::Render::PostProcessFeatureProcessorInterface* postProcessFeatureProcessor = + m_scene->GetFeatureProcessor(); + AZ::Render::ExposureControlSettingsInterface* exposureControlSettingInterface = + postProcessFeatureProcessor->GetOrCreateSettingsInterface(m_postProcessEntity->GetId()) + ->GetOrCreateExposureControlSettingsInterface(); + + Camera::Configuration cameraConfig; + cameraConfig.m_fovRadians = AZ::Constants::HalfPi; + cameraConfig.m_nearClipDistance = DepthNear; + + preset->ApplyLightingPreset( + iblFeatureProcessor, m_skyboxFeatureProcessor, exposureControlSettingInterface, m_directionalLightFeatureProcessor, + cameraConfig, m_lightHandles, nullptr, AZ::RPI::MaterialPropertyIndex::Null, false); + } +} // namespace EMStudio diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.h new file mode 100644 index 0000000000..dd420c175c --- /dev/null +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.h @@ -0,0 +1,88 @@ +/* + * 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 + * + */ + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace AZ +{ + class Entity; + class Component; + + namespace Render + { + class DisplayMapperFeatureProcessorInterface; + class DirectionalLightFeatureProcessorInterface; + class MeshFeatureProcessorInterface; + } + + namespace RPI + { + class WindowContext; + } +} + +namespace EMStudio +{ + class AnimViewportRenderer + { + public: + AZ_CLASS_ALLOCATOR(AnimViewportRenderer, AZ::SystemAllocator, 0); + + AnimViewportRenderer(AZ::RPI::ViewportContextPtr viewportContext); + ~AnimViewportRenderer(); + + void Reinit(); + + private: + + // This function resets the light, camera and other environment settings. + void ResetEnvironment(); + + // This function creates in-editor entities for all actor assets stored in the actor manager, + // and deletes all the actor entities that no longer has an actor asset in the actor manager. + // Those entities are used in atom render viewport to visualize actors in animation editor. + void ReinitActorEntities(); + + AZ::Entity* CreateActorEntity(AZ::Data::Asset actorAsset); + + AZ::Entity* FindActorEntity(AZ::Data::Asset actorAsset) const; + void SetLightingPreset(const AZ::Render::LightingPreset* preset); + + AZStd::shared_ptr m_windowContext; + AZStd::unique_ptr m_entityContext; + AZStd::shared_ptr m_frameworkScene; + AZ::RPI::ScenePtr m_scene; + AZ::RPI::RenderPipelinePtr m_renderPipeline; + AZ::Render::DirectionalLightFeatureProcessorInterface* m_directionalLightFeatureProcessor = nullptr; + AZ::Render::DisplayMapperFeatureProcessorInterface* m_displayMapperFeatureProcessor = nullptr; + AZ::Render::SkyBoxFeatureProcessorInterface* m_skyboxFeatureProcessor = nullptr; + AZ::Render::MeshFeatureProcessorInterface* m_meshFeatureProcessor = nullptr; + + AZ::Entity* m_postProcessEntity = nullptr; + AZ::Entity* m_iblEntity = nullptr; + AZ::Entity* m_cameraEntity = nullptr; + AZ::Component* m_cameraComponent = nullptr; + AZ::Entity* m_modelEntity = nullptr; + AZ::Data::AssetId m_modelAssetId; + AZ::Entity* m_gridEntity = nullptr; + AZStd::vector m_actorEntities; + + AZStd::vector m_lightHandles; + }; +} diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportSettings.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportSettings.cpp new file mode 100644 index 0000000000..347e077af3 --- /dev/null +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportSettings.cpp @@ -0,0 +1,71 @@ +/* + * 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 + * + */ +#include + +namespace EMStudio::ViewportUtil +{ + constexpr AZStd::string_view CameraRotateSmoothnessSetting = "/Amazon/Preferences/Editor/Camera/RotateSmoothness"; + constexpr AZStd::string_view CameraTranslateSmoothnessSetting = "/Amazon/Preferences/Editor/Camera/TranslateSmoothness"; + constexpr AZStd::string_view CameraTranslateSmoothingSetting = "/Amazon/Preferences/Editor/Camera/TranslateSmoothing"; + constexpr AZStd::string_view CameraRotateSmoothingSetting = "/Amazon/Preferences/Editor/Camera/RotateSmoothing"; + + constexpr AZStd::string_view CameraOrbitLookIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitLookId"; + constexpr AZStd::string_view CameraTranslateForwardIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateForwardId"; + constexpr AZStd::string_view CameraTranslateBackwardIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateBackwardId"; + constexpr AZStd::string_view CameraTranslateLeftIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateLeftId"; + constexpr AZStd::string_view CameraTranslateRightIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateRightId"; + constexpr AZStd::string_view CameraTranslateUpIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateUpId"; + constexpr AZStd::string_view CameraTranslateDownIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateUpDownId"; + constexpr AZStd::string_view CameraTranslateBoostIdSetting = "/Amazon/Preferences/Editor/Camera/TranslateBoostId"; + + AzFramework::TranslateCameraInputChannelIds BuildTranslateCameraInputChannelIds() + { + AzFramework::TranslateCameraInputChannelIds translateCameraInputChannelIds; + translateCameraInputChannelIds.m_leftChannelId = + AzFramework::InputChannelId(GetRegistry(CameraTranslateLeftIdSetting, AZStd::string("keyboard_key_alphanumeric_A")).c_str()); + translateCameraInputChannelIds.m_rightChannelId = + AzFramework::InputChannelId(GetRegistry(CameraTranslateRightIdSetting, AZStd::string("keyboard_key_alphanumeric_D")).c_str()); + translateCameraInputChannelIds.m_forwardChannelId = + AzFramework::InputChannelId(GetRegistry(CameraTranslateForwardIdSetting, AZStd::string("keyboard_key_alphanumeric_W")).c_str()); + translateCameraInputChannelIds.m_backwardChannelId = AzFramework::InputChannelId( + GetRegistry(CameraTranslateBackwardIdSetting, AZStd::string("keyboard_key_alphanumeric_S")).c_str()); + translateCameraInputChannelIds.m_upChannelId = + AzFramework::InputChannelId(GetRegistry(CameraTranslateUpIdSetting, AZStd::string("keyboard_key_alphanumeric_E")).c_str()); + translateCameraInputChannelIds.m_downChannelId = + AzFramework::InputChannelId(GetRegistry(CameraTranslateDownIdSetting, AZStd::string("keyboard_key_alphanumeric_Q")).c_str()); + translateCameraInputChannelIds.m_boostChannelId = + AzFramework::InputChannelId(GetRegistry(CameraTranslateBoostIdSetting, AZStd::string("keyboard_key_modifier_shift_l")).c_str()); + + return translateCameraInputChannelIds; + } + + float CameraRotateSmoothness() + { + return aznumeric_cast(GetRegistry(CameraRotateSmoothnessSetting, 5.0)); + } + + float CameraTranslateSmoothness() + { + return aznumeric_cast(GetRegistry(CameraTranslateSmoothnessSetting, 5.0)); + } + + bool CameraRotateSmoothingEnabled() + { + return GetRegistry(CameraRotateSmoothingSetting, true); + } + + bool CameraTranslateSmoothingEnabled() + { + return GetRegistry(CameraTranslateSmoothingSetting, true); + } + + AzFramework::InputChannelId BuildRotateCameraInputId() + { + return AzFramework::InputChannelId(GetRegistry(CameraOrbitLookIdSetting, AZStd::string("mouse_button_left")).c_str()); + } +} diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportSettings.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportSettings.h new file mode 100644 index 0000000000..5fa14a8aae --- /dev/null +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportSettings.h @@ -0,0 +1,37 @@ +/* + * 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 + * + */ +#pragma once +#include +#include + +namespace EMStudio::ViewportUtil +{ + template + AZStd::remove_cvref_t GetRegistry(const AZStd::string_view setting, T&& defaultValue) + { + AZStd::remove_cvref_t value = AZStd::forward(defaultValue); + if (const auto* registry = AZ::SettingsRegistry::Get()) + { + T potentialValue; + if (registry->Get(potentialValue, setting)) + { + value = AZStd::move(potentialValue); + } + } + + return value; + } + + float CameraRotateSmoothness(); + float CameraTranslateSmoothness(); + bool CameraRotateSmoothingEnabled(); + bool CameraTranslateSmoothingEnabled(); + + AzFramework::TranslateCameraInputChannelIds BuildTranslateCameraInputChannelIds(); + AzFramework::InputChannelId BuildRotateCameraInputId(); +} diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.cpp new file mode 100644 index 0000000000..6a6c9df901 --- /dev/null +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.cpp @@ -0,0 +1,103 @@ +/* + * 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 + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace EMStudio +{ + AnimViewportWidget::AnimViewportWidget(QWidget* parent) + : AtomToolsFramework::RenderViewportWidget(parent) + { + setObjectName(QString::fromUtf8("AtomViewportWidget")); + QSizePolicy qSize(QSizePolicy::Preferred, QSizePolicy::Preferred); + qSize.setHorizontalStretch(0); + qSize.setVerticalStretch(0); + qSize.setHeightForWidth(sizePolicy().hasHeightForWidth()); + setSizePolicy(qSize); + setAutoFillBackground(false); + setStyleSheet(QString::fromUtf8("")); + + m_renderer = AZStd::make_unique(GetViewportContext()); + + SetupCameras(); + SetupCameraController(); + } + + void AnimViewportWidget::SetupCameras() + { + m_rotateCamera = AZStd::make_shared(EMStudio::ViewportUtil::BuildRotateCameraInputId()); + + const auto translateCameraInputChannelIds = EMStudio::ViewportUtil::BuildTranslateCameraInputChannelIds(); + m_translateCamera = AZStd::make_shared( + translateCameraInputChannelIds, AzFramework::LookTranslation, AzFramework::TranslatePivotLook); + m_translateCamera.get()->m_translateSpeedFn = [] + { + return 3.0f; + }; + + m_orbitDollyScrollCamera = AZStd::make_shared(); + } + + void AnimViewportWidget::SetupCameraController() + { + auto controller = AZStd::make_shared(); + controller->SetCameraViewportContextBuilderCallback( + [viewportId = + GetViewportContext()->GetId()](AZStd::unique_ptr& cameraViewportContext) + { + cameraViewportContext = AZStd::make_unique(viewportId); + }); + + controller->SetCameraPriorityBuilderCallback( + [](AtomToolsFramework::CameraControllerPriorityFn& cameraControllerPriorityFn) + { + cameraControllerPriorityFn = AtomToolsFramework::DefaultCameraControllerPriority; + }); + + controller->SetCameraPropsBuilderCallback( + [](AzFramework::CameraProps& cameraProps) + { + cameraProps.m_rotateSmoothnessFn = [] + { + return EMStudio::ViewportUtil::CameraRotateSmoothness(); + }; + + cameraProps.m_translateSmoothnessFn = [] + { + return EMStudio::ViewportUtil::CameraTranslateSmoothness(); + }; + + cameraProps.m_rotateSmoothingEnabledFn = [] + { + return EMStudio::ViewportUtil::CameraRotateSmoothingEnabled(); + }; + + cameraProps.m_translateSmoothingEnabledFn = [] + { + return EMStudio::ViewportUtil::CameraTranslateSmoothingEnabled(); + }; + }); + + controller->SetCameraListBuilderCallback( + [this](AzFramework::Cameras& cameras) + { + cameras.AddCamera(m_rotateCamera); + cameras.AddCamera(m_translateCamera); + cameras.AddCamera(m_orbitDollyScrollCamera); + }); + GetControllerList()->Add(controller); + } +} // namespace EMStudio diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.h new file mode 100644 index 0000000000..7c2e085f84 --- /dev/null +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.h @@ -0,0 +1,33 @@ +/* + * 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 + * + */ +#pragma once + +#include +#include + +namespace EMStudio +{ + class AnimViewportRenderer; + + class AnimViewportWidget + : public AtomToolsFramework::RenderViewportWidget + { + public: + AnimViewportWidget(QWidget* parent = nullptr); + AnimViewportRenderer* GetAnimViewportRenderer() { return m_renderer.get(); } + + private: + void SetupCameras(); + void SetupCameraController(); + + AZStd::unique_ptr m_renderer; + AZStd::shared_ptr m_rotateCamera; + AZStd::shared_ptr m_translateCamera; + AZStd::shared_ptr m_orbitDollyScrollCamera; + }; +} diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.cpp new file mode 100644 index 0000000000..91a34e16cd --- /dev/null +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.cpp @@ -0,0 +1,140 @@ +/* + * 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 + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +namespace EMStudio +{ + AZ_CLASS_ALLOCATOR_IMPL(AtomRenderPlugin, EMotionFX::EditorAllocator, 0); + + AtomRenderPlugin::AtomRenderPlugin() + : DockWidgetPlugin() + { + } + + AtomRenderPlugin::~AtomRenderPlugin() + { + + } + + const char* AtomRenderPlugin::GetName() const + { + return "Atom Render Window (Preview)"; + } + + uint32 AtomRenderPlugin::GetClassID() const + { + return static_cast(AtomRenderPlugin::CLASS_ID); + } + + const char* AtomRenderPlugin::GetCreatorName() const + { + return "O3DE"; + } + + float AtomRenderPlugin::GetVersion() const + { + return 1.0f; + } + + bool AtomRenderPlugin::GetIsClosable() const + { + return true; + } + + bool AtomRenderPlugin::GetIsFloatable() const + { + return true; + } + + bool AtomRenderPlugin::GetIsVertical() const + { + return false; + } + + EMStudioPlugin* AtomRenderPlugin::Clone() + { + return new AtomRenderPlugin(); + } + + EMStudioPlugin::EPluginType AtomRenderPlugin::GetPluginType() const + { + return EMStudioPlugin::PLUGINTYPE_RENDERING; + } + + void AtomRenderPlugin::ReinitRenderer() + { + m_animViewportWidget->GetAnimViewportRenderer()->Reinit(); + } + + bool AtomRenderPlugin::Init() + { + m_innerWidget = new QWidget(); + m_dock->setWidget(m_innerWidget); + + QVBoxLayout* verticalLayout = new QVBoxLayout(m_innerWidget); + verticalLayout->setSizeConstraint(QLayout::SetNoConstraint); + verticalLayout->setSpacing(1); + verticalLayout->setMargin(0); + m_animViewportWidget = new AnimViewportWidget(m_innerWidget); + verticalLayout->addWidget(m_animViewportWidget); + + // Register command callbacks. + m_importActorCallback = new ImportActorCallback(false); + m_removeActorCallback = new RemoveActorCallback(false); + EMStudioManager::GetInstance()->GetCommandManager()->RegisterCommandCallback("ImportActor", m_importActorCallback); + EMStudioManager::GetInstance()->GetCommandManager()->RegisterCommandCallback("RemoveActor", m_removeActorCallback); + + return true; + } + + // Command callbacks + bool ReinitAtomRenderPlugin() + { + EMStudioPlugin* plugin = EMStudio::GetPluginManager()->FindActivePlugin(static_cast(AtomRenderPlugin::CLASS_ID)); + if (!plugin) + { + AZ_Error("AtomRenderPlugin", false, "Cannot execute command callback. Atom render plugin does not exist."); + return false; + } + + AtomRenderPlugin* atomRenderPlugin = static_cast(plugin); + atomRenderPlugin->ReinitRenderer(); + + return true; + } + + bool AtomRenderPlugin::ImportActorCallback::Execute( + [[maybe_unused]] MCore::Command* command, [[maybe_unused]] const MCore::CommandLine& commandLine) + { + return ReinitAtomRenderPlugin(); + } + bool AtomRenderPlugin::ImportActorCallback::Undo( + [[maybe_unused]] MCore::Command* command, [[maybe_unused]] const MCore::CommandLine& commandLine) + { + return ReinitAtomRenderPlugin(); + } + + bool AtomRenderPlugin::RemoveActorCallback::Execute( + [[maybe_unused]] MCore::Command* command, [[maybe_unused]] const MCore::CommandLine& commandLine) + { + return ReinitAtomRenderPlugin(); + } + bool AtomRenderPlugin::RemoveActorCallback::Undo( + [[maybe_unused]] MCore::Command* command, [[maybe_unused]] const MCore::CommandLine& commandLine) + { + return ReinitAtomRenderPlugin(); + } +}// namespace EMStudio diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.h new file mode 100644 index 0000000000..1516b45e77 --- /dev/null +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.h @@ -0,0 +1,61 @@ +/* + * 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 + * + */ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include + +#include +#include +#endif + +namespace AZ +{ + class Entity; +} + +namespace EMStudio +{ + class AtomRenderPlugin + : public DockWidgetPlugin + { + public: + AZ_CLASS_ALLOCATOR_DECL + + enum + { + CLASS_ID = 0x32b0c04d + }; + AtomRenderPlugin(); + ~AtomRenderPlugin(); + + // Plugin information + const char* GetName() const override; + uint32 GetClassID() const override; + const char* GetCreatorName() const override; + float GetVersion() const override; + bool GetIsClosable() const override; + bool GetIsFloatable() const override; + bool GetIsVertical() const override; + bool Init() override; + EMStudioPlugin* Clone(); + EMStudioPlugin::EPluginType GetPluginType() const override; + + void ReinitRenderer(); + + private: + MCORE_DEFINECOMMANDCALLBACK(ImportActorCallback); + MCORE_DEFINECOMMANDCALLBACK(RemoveActorCallback); + ImportActorCallback* m_importActorCallback = nullptr; + RemoveActorCallback* m_removeActorCallback = nullptr; + QWidget* m_innerWidget = nullptr; + AnimViewportWidget* m_animViewportWidget = nullptr; + }; +}// namespace EMStudio diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/emotionfx_atom_editor_files.cmake b/Gems/AtomLyIntegration/EMotionFXAtom/Code/emotionfx_atom_editor_files.cmake index 6401beb232..a88581099f 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/emotionfx_atom_editor_files.cmake +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/emotionfx_atom_editor_files.cmake @@ -8,4 +8,14 @@ set(FILES Source/ActorModule.cpp + Source/Editor/EditorSystemComponent.h + Source/Editor/EditorSystemComponent.cpp + Tools/EMStudio/AtomRenderPlugin.h + Tools/EMStudio/AtomRenderPlugin.cpp + Tools/EMStudio/AnimViewportWidget.h + Tools/EMStudio/AnimViewportWidget.cpp + Tools/EMStudio/AnimViewportRenderer.h + Tools/EMStudio/AnimViewportRenderer.cpp + Tools/EMStudio/AnimViewportSettings.h + Tools/EMStudio/AnimViewportSettings.cpp ) diff --git a/Gems/EMotionFX/Code/CMakeLists.txt b/Gems/EMotionFX/Code/CMakeLists.txt index dace02b2ae..67d0ba6d85 100644 --- a/Gems/EMotionFX/Code/CMakeLists.txt +++ b/Gems/EMotionFX/Code/CMakeLists.txt @@ -109,6 +109,8 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) AZ::AzToolsFramework Legacy::Editor.Headers 3rdParty::OpenGLInterface + Gem::AtomToolsFramework.Static + Gem::AtomToolsFramework.Editor COMPILE_DEFINITIONS PUBLIC EMFX_EMSTUDIOLYEMBEDDED diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ActorCommands.cpp b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ActorCommands.cpp index 85bb726822..57e206560a 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ActorCommands.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ActorCommands.cpp @@ -22,6 +22,7 @@ #include "CommandManager.h" #include #include +#include namespace CommandSystem @@ -729,7 +730,8 @@ namespace CommandSystem m_oldWorkspaceDirtyFlag = GetCommandManager()->GetWorkspaceDirtyFlag(); // get rid of the actor - EMotionFX::GetActorManager().UnregisterActor(EMotionFX::GetActorManager().FindSharedActorByID(actor->GetID())); + const AZ::Data::AssetId actorAssetId = EMotionFX::GetActorManager().FindAssetIdByActorId(actor->GetID()); + EMotionFX::GetActorManager().UnregisterActor(actorAssetId); // mark the workspace as dirty GetCommandManager()->SetWorkspaceDirtyFlag(true); @@ -818,7 +820,6 @@ namespace CommandSystem { continue; } - // ignore visualization actor instances if (actorInstance->GetIsUsedForVisualization()) { @@ -849,12 +850,6 @@ namespace CommandSystem // get the current actor EMotionFX::Actor* actor = EMotionFX::GetActorManager().GetActor(i); - // ignore runtime-owned actors - if (actor->GetIsOwnedByRuntime()) - { - continue; - } - // ignore visualization actors if (actor->GetIsUsedForVisualization()) { diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ImporterCommands.cpp b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ImporterCommands.cpp index 168de93e38..ea3f816e86 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ImporterCommands.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ImporterCommands.cpp @@ -17,6 +17,7 @@ #include #include "CommandManager.h" #include +#include namespace CommandSystem @@ -65,35 +66,29 @@ namespace CommandSystem filename = EMotionFX::EMotionFXManager::ResolvePath(filename.c_str()); } - // check if we have already loaded the actor - EMotionFX::Actor* actorFromManager = EMotionFX::GetActorManager().FindActorByFileName(filename.c_str()); - if (actorFromManager) + AZ::Data::AssetId actorAssetId; + EBUS_EVENT_RESULT( + actorAssetId, AZ::Data::AssetCatalogRequestBus, GetAssetIdByPath, filename.c_str(), AZ::Data::s_invalidAssetType, false); + if (!actorAssetId.IsValid()) { - AZStd::to_string(outResult, actorFromManager->GetID()); - return true; - } - - // init the settings - EMotionFX::Importer::ActorSettings settings; - - // extract default values from the command syntax automatically, if they aren't specified explicitly - settings.m_loadLimits = parameters.GetValueAsBool("loadLimits", this); - settings.m_loadMorphTargets = parameters.GetValueAsBool("loadMorphTargets", this); - settings.m_loadSkeletalLoDs = parameters.GetValueAsBool("loadSkeletalLODs", this); - settings.m_dualQuatSkinning = parameters.GetValueAsBool("dualQuatSkinning", this); - - // try to load the actor - AZStd::shared_ptr actor {EMotionFX::GetImporter().LoadActor(filename.c_str(), &settings)}; - if (!actor) - { - outResult = AZStd::string::format("Failed to load actor from '%s'. File may not exist at this path or may have incorrect permissions", filename.c_str()); + outResult = AZStd::string::format("Cannot import actor. Cannot find asset at path %s.", filename.c_str()); return false; } - // Because the actor is directly loaded from disk (without going through an actor asset), we need to ask for a blocking - // load for the asset that actor is depend on. - actor->Finalize(EMotionFX::Actor::LoadRequirement::RequireBlockingLoad); + // check if we have already loaded the actor + const size_t actorIndex = EMotionFX::GetActorManager().FindActorIndex(actorAssetId); + if (actorIndex != InvalidIndex) + { + return true; + } + // Do a blocking load of the asset. + AZ::Data::Asset actorAsset = + AZ::Data::AssetManager::Instance().GetAsset( + actorAssetId, AZ::Data::AssetLoadBehavior::Default); + actorAsset.BlockUntilLoadComplete(); + + EMotionFX::Actor* actor = actorAsset->GetActor(); // set the actor id in case we have specified it as parameter if (actorID != MCORE_INVALIDINDEX32) { @@ -113,7 +108,6 @@ namespace CommandSystem GetCommandManager()->ExecuteCommandInsideCommand(AZStd::string::format("Select -actorID %i", actor->GetID()).c_str(), outResult); } - // mark the workspace as dirty m_oldWorkspaceDirtyFlag = GetCommandManager()->GetWorkspaceDirtyFlag(); GetCommandManager()->SetWorkspaceDirtyFlag(true); @@ -121,7 +115,8 @@ namespace CommandSystem // return the id of the newly created actor AZStd::to_string(outResult, actor->GetID()); - EMotionFX::GetActorManager().RegisterActor(AZStd::move(actor)); + // Register actor asset. + EMotionFX::GetActorManager().RegisterActor(AZStd::move(actorAsset)); return true; } @@ -145,14 +140,14 @@ namespace CommandSystem } // find the actor based on the given id - AZStd::shared_ptr actor = EMotionFX::GetActorManager().FindSharedActorByID(actorID); - if (actor == nullptr) + AZ::Data::AssetId actorAssetId = EMotionFX::GetActorManager().FindAssetIdByActorId(actorID); + if (!actorAssetId.IsValid()) { outResult = AZStd::string::format("Cannot remove actor. Actor ID %i is not valid.", actorID); return false; } - EMotionFX::GetActorManager().UnregisterActor(actor); + EMotionFX::GetActorManager().UnregisterActor(actorAssetId); // update our render actors AZStd::string updateRenderActorsResult; diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/SelectionCommands.cpp b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/SelectionCommands.cpp index bcc9769c44..7e1a9fe0f5 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/SelectionCommands.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/SelectionCommands.cpp @@ -183,11 +183,6 @@ namespace CommandSystem for (size_t i = 0; i < numActors; ++i) { EMotionFX::Actor* actor = EMotionFX::GetActorManager().GetActor(i); - - if (actor->GetIsOwnedByRuntime()) - { - continue; - } if (unselect == false) { @@ -211,11 +206,6 @@ namespace CommandSystem return false; } - if (actor->GetIsOwnedByRuntime()) - { - return false; - } - if (unselect == false) { selection.AddActor(actor); @@ -244,11 +234,6 @@ namespace CommandSystem { EMotionFX::Actor* actor = EMotionFX::GetActorManager().GetActor(i); - if (actor->GetIsOwnedByRuntime()) - { - continue; - } - if (AzFramework::StringFunc::Equal(valueString.c_str(), actor->GetName(), false /* no case */)) { if (unselect == false) diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.cpp index 4cba50138a..3d5e4fa413 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.cpp @@ -8,7 +8,6 @@ #include #include -#include #include #include #include diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.h b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.h index e94137b317..d2db7d91c5 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.h +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Actor/ActorGroupExporter.h @@ -8,7 +8,6 @@ #pragma once #include -#include #include #include #include @@ -44,7 +43,7 @@ namespace EMotionFX static AZStd::optional GetFirstProductByType( const ActorGroupExportContext& context, AZ::Data::AssetType type); - AutoRegisteredActor m_actor; + AZStd::shared_ptr m_actor; AZStd::vector m_actorMaterialReferences; }; } // namespace Pipeline diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp index 3e592113b1..861271fdb3 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp @@ -91,9 +91,6 @@ namespace EMotionFX m_simulatedObjectSetup = AZStd::make_shared(this); m_optimizeSkeleton = false; -#if defined(EMFX_DEVELOPMENT_BUILD) - m_isOwnedByRuntime = false; -#endif // EMFX_DEVELOPMENT_BUILD // make sure we have at least allocated the first LOD of materials and facial setups m_materials.reserve(4); // reserve space for 4 lods @@ -2074,25 +2071,6 @@ namespace EMotionFX return m_usedForVisualization; } - void Actor::SetIsOwnedByRuntime(bool isOwnedByRuntime) - { -#if defined(EMFX_DEVELOPMENT_BUILD) - m_isOwnedByRuntime = isOwnedByRuntime; -#else - AZ_UNUSED(isOwnedByRuntime); -#endif - } - - - bool Actor::GetIsOwnedByRuntime() const - { -#if defined(EMFX_DEVELOPMENT_BUILD) - return m_isOwnedByRuntime; -#else - return true; -#endif - } - const AZ::Aabb& Actor::GetStaticAabb() const { return m_staticAabb; diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Actor.h b/Gems/EMotionFX/Code/EMotionFX/Source/Actor.h index aa5c5df45c..dc83972d40 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Actor.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Actor.h @@ -720,12 +720,6 @@ namespace EMotionFX void SetIsUsedForVisualization(bool flag); bool GetIsUsedForVisualization() const; - /** - * Marks the actor as used by the engine runtime, as opposed to the tool suite. - */ - void SetIsOwnedByRuntime(bool isOwnedByRuntime); - bool GetIsOwnedByRuntime() const; - /** * Recursively find the parent bone that is enabled in a given LOD, starting from a given node. * For example if you have a finger bone, while the finger bones are disabled in the skeletal LOD, this function will return the index to the hand bone. @@ -940,8 +934,5 @@ namespace EMotionFX bool m_usedForVisualization; /**< Indicates if the actor is used for visualization specific things and is not used as a normal in-game actor. */ bool m_optimizeSkeleton; /**< Indicates if we should perform/ */ bool m_isReady = false; /**< If actor as well as its dependent files are fully loaded and initialized.*/ -#if defined(EMFX_DEVELOPMENT_BUILD) - bool m_isOwnedByRuntime; /**< Set if the actor is used/owned by the engine runtime. */ -#endif // EMFX_DEVELOPMENT_BUILD }; } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/ActorManager.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/ActorManager.cpp index 681efb6039..184aac6e2c 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/ActorManager.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/ActorManager.cpp @@ -31,7 +31,6 @@ namespace EMotionFX SetScheduler(MultiThreadScheduler::Create()); // reserve memory - m_actors.reserve(512); m_actorInstances.reserve(1024); m_rootActorInstances.reserve(1024); } @@ -111,20 +110,23 @@ namespace EMotionFX // register the actor - void ActorManager::RegisterActor(AZStd::shared_ptr actor) + void ActorManager::RegisterActor(ActorAssetData actorAsset) { LockActors(); // check if we already registered - if (FindActorIndex(actor.get()) != InvalidIndex) + if (FindActorIndex(actorAsset.GetId()) != InvalidIndex) { - MCore::LogWarning("EMotionFX::ActorManager::RegisterActor() - The actor at location 0x%x has already been registered as actor, most likely already by the LoadActor of the importer.", actor.get()); + MCore::LogWarning( + "EMotionFX::ActorManager::RegisterActor() - The actor %s has already been registered as actor, most likely " + "already by the LoadActor of the importer.", + actorAsset->GetActor()->GetName()); UnlockActors(); return; } // register it - m_actors.emplace_back(AZStd::move(actor)); + m_actorAssets.emplace_back(AZStd::move(actorAsset)); UnlockActors(); } @@ -146,60 +148,82 @@ namespace EMotionFX Actor* ActorManager::FindActorByName(const char* actorName) const { // get the number of actors and iterate through them - const auto found = AZStd::find_if(m_actors.begin(), m_actors.end(), [actorName](const AZStd::shared_ptr& a) + const auto found = AZStd::find_if( + m_actorAssets.begin(), m_actorAssets.end(), + [actorName](const ActorAssetData& a) { - return a->GetNameString() == actorName; + return a->GetActor()->GetNameString() == actorName; }); - return (found != m_actors.end()) ? found->get() : nullptr; + return (found != m_actorAssets.end()) ? (*found)->GetActor() : nullptr; } // find the actor for a given filename Actor* ActorManager::FindActorByFileName(const char* fileName) const { - const auto found = AZStd::find_if(m_actors.begin(), m_actors.end(), [fileName](const AZStd::shared_ptr& a) + const auto found = AZStd::find_if( + m_actorAssets.begin(), m_actorAssets.end(), + [fileName](const ActorAssetData& a) { - return AzFramework::StringFunc::Equal(a->GetFileNameString().c_str(), fileName, false /* no case */); + return AzFramework::StringFunc::Equal( + a->GetActor()->GetFileNameString().c_str(), fileName, false /* no case */); }); - return (found != m_actors.end()) ? found->get() : nullptr; + return (found != m_actorAssets.end()) ? (*found)->GetActor() : nullptr; } // find the leader actor record for a given actor - size_t ActorManager::FindActorIndex(Actor* actor) const + size_t ActorManager::FindActorIndex(AZ::Data::AssetId assetId) const { - const auto found = AZStd::find_if(m_actors.begin(), m_actors.end(), [actor](const AZStd::shared_ptr& a) + const auto found = AZStd::find_if( + m_actorAssets.begin(), m_actorAssets.end(), + [assetId](const ActorAssetData& a) { - return a.get() == actor; + return a.GetId() == assetId; }); - return (found != m_actors.end()) ? AZStd::distance(m_actors.begin(), found) : InvalidIndex; + return (found != m_actorAssets.end()) ? AZStd::distance(m_actorAssets.begin(), found) : InvalidIndex; } + size_t ActorManager::FindActorIndex(const Actor* actor) const + { + const auto found = AZStd::find_if( + m_actorAssets.begin(), m_actorAssets.end(), + [actor](const ActorAssetData& a) + { + return a->GetActor() == actor; + }); + + return (found != m_actorAssets.end()) ? AZStd::distance(m_actorAssets.begin(), found) : InvalidIndex; + } // find the actor for a given actor name size_t ActorManager::FindActorIndexByName(const char* actorName) const { - const auto found = AZStd::find_if(m_actors.begin(), m_actors.end(), [actorName](const AZStd::shared_ptr& a) + const auto found = AZStd::find_if( + m_actorAssets.begin(), m_actorAssets.end(), + [actorName](const ActorAssetData& a) { - return a->GetNameString() == actorName; + return a->GetActor()->GetNameString() == actorName; }); - return (found != m_actors.end()) ? AZStd::distance(m_actors.begin(), found) : InvalidIndex; + return (found != m_actorAssets.end()) ? AZStd::distance(m_actorAssets.begin(), found) : InvalidIndex; } // find the actor for a given actor filename size_t ActorManager::FindActorIndexByFileName(const char* filename) const { - const auto found = AZStd::find_if(m_actors.begin(), m_actors.end(), [filename](const AZStd::shared_ptr& a) + const auto found = AZStd::find_if( + m_actorAssets.begin(), m_actorAssets.end(), + [filename](const ActorAssetData& a) { - return a->GetFileNameString() == filename; + return a->GetActor()->GetFileNameString() == filename; }); - return (found != m_actors.end()) ? AZStd::distance(m_actors.begin(), found) : InvalidIndex; + return (found != m_actorAssets.end()) ? AZStd::distance(m_actorAssets.begin(), found) : InvalidIndex; } @@ -237,22 +261,26 @@ namespace EMotionFX // find the actor by the identification number Actor* ActorManager::FindActorByID(uint32 id) const { - const auto found = AZStd::find_if(m_actors.begin(), m_actors.end(), [id](const AZStd::shared_ptr& a) + const auto found = AZStd::find_if( + m_actorAssets.begin(), m_actorAssets.end(), + [id](const ActorAssetData& a) { - return a->GetID() == id; + return a->GetActor()->GetID() == id; }); - return (found != m_actors.end()) ? found->get() : nullptr; + return (found != m_actorAssets.end()) ? (*found)->GetActor() : nullptr; } - AZStd::shared_ptr ActorManager::FindSharedActorByID(uint32 id) const + AZ::Data::AssetId ActorManager::FindAssetIdByActorId(uint32 id) const { - const auto found = AZStd::find_if(m_actors.begin(), m_actors.end(), [id](const AZStd::shared_ptr& a) + const auto found = AZStd::find_if( + m_actorAssets.begin(), m_actorAssets.end(), + [id](const ActorAssetData& a) { - return a->GetID() == id; + return a->GetActor()->GetID() == id; }); - return (found != m_actors.end()) ? *found : nullptr; + return (found != m_actorAssets.end()) ? found->GetId() : AZ::Data::AssetId(); } @@ -264,14 +292,20 @@ namespace EMotionFX // unregister an actor - void ActorManager::UnregisterActor(const AZStd::shared_ptr& actor) + void ActorManager::UnregisterActor(AZ::Data::AssetId actorAssetID) { LockActors(); - auto result = AZStd::find(m_actors.begin(), m_actors.end(), actor); - if (result != m_actors.end()) + const auto found = AZStd::find_if( + m_actorAssets.begin(), m_actorAssets.end(), + [actorAssetID](const ActorAssetData& a) + { + return a.GetId() == actorAssetID; + }); + if (found != m_actorAssets.end()) { - m_actors.erase(result); + m_actorAssets.erase(found); } + UnlockActors(); } @@ -297,7 +331,7 @@ namespace EMotionFX LockActors(); // clear all actors - m_actors.clear(); + m_actorAssets.clear(); // TODO: what if there are still references to the actors inside the list of registered actor instances? UnlockActors(); @@ -390,7 +424,13 @@ namespace EMotionFX Actor* ActorManager::GetActor(size_t nr) const { - return m_actors[nr].get(); + return m_actorAssets[nr]->GetActor(); + } + + + ActorAssetData ActorManager::GetActorAsset(size_t nr) const + { + return m_actorAssets[nr]; } diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/ActorManager.h b/Gems/EMotionFX/Code/EMotionFX/Source/ActorManager.h index ff78250141..003153b36c 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/ActorManager.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/ActorManager.h @@ -16,7 +16,8 @@ #include #include #include - +#include +#include namespace EMotionFX { @@ -47,7 +48,7 @@ namespace EMotionFX * Register an actor. * @param actor The actor to register. */ - void RegisterActor(AZStd::shared_ptr actor); + void RegisterActor(ActorAssetData actorAsset); /** * Unregister all actors. @@ -60,14 +61,14 @@ namespace EMotionFX * Unregister a specific actor. * @param actor The actor you passed to the RegisterActor function sometime before. */ - void UnregisterActor(const AZStd::shared_ptr& actor); + void UnregisterActor(AZ::Data::AssetId actorAssetID); /** * Get the number of registered actors. * This does not include the clones that have been optionally created. * @result The number of registered actors. */ - MCORE_INLINE size_t GetNumActors() const { return m_actors.size(); } + MCORE_INLINE size_t GetNumActors() const { return m_actorAssets.size(); } /** * Get a given actor. @@ -78,6 +79,7 @@ namespace EMotionFX * @result A reference to the actor object that contains the array of Actor objects. */ Actor* GetActor(size_t nr) const; + ActorAssetData GetActorAsset(size_t nr) const; /** * Find the given actor by name. @@ -99,7 +101,8 @@ namespace EMotionFX * @param actor The actor object you once passed to RegisterActor. * @result Returns the actor number, which is in range of [0..GetNumActors()-1], or returns MCORE_INVALIDINDEX32 when not found. */ - size_t FindActorIndex(Actor* actor) const; + size_t FindActorIndex(AZ::Data::AssetId assetId) const; + size_t FindActorIndex(const Actor* actor) const; /** * Find the actor number for a given actor name. @@ -160,7 +163,7 @@ namespace EMotionFX */ Actor* FindActorByID(uint32 id) const; - AZStd::shared_ptr FindSharedActorByID(uint32 id) const; + AZ::Data::AssetId FindAssetIdByActorId(uint32 id) const; /** * Check if the given actor instance is registered. @@ -255,9 +258,9 @@ namespace EMotionFX void UnlockActors(); private: - AZStd::vector m_actorInstances; /**< The registered actor instances. */ - AZStd::vector> m_actors; /**< The registered actors. */ - AZStd::vector m_rootActorInstances; /**< Root actor instances (roots of all attachment chains). */ + AZStd::vector m_actorInstances; /**< The registered actor instances. */ + AZStd::vector m_actorAssets; + AZStd::vector m_rootActorInstances; /**< Root actor instances (roots of all attachment chains). */ ActorUpdateScheduler* m_scheduler; /**< The update scheduler to use. */ MCore::MutexRecursive m_actorLock; /**< The multithread lock for touching the actors array. */ MCore::MutexRecursive m_actorInstanceLock; /**< The multithread lock for touching the actor instances array. */ diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/AutoRegisteredActor.h b/Gems/EMotionFX/Code/EMotionFX/Source/AutoRegisteredActor.h deleted file mode 100644 index 8304976b15..0000000000 --- a/Gems/EMotionFX/Code/EMotionFX/Source/AutoRegisteredActor.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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 - * - */ - -#pragma once - -#include -#include -#include - -namespace EMotionFX -{ - class Actor; - - /** - * @brief An Actor pointer that unregisters itself when it goes out of - * scope - * - * This class allows for simple functionality of automatically registering - * and unregistering an actor from the manager. Its primary use case is the - * ActorAsset, that shares ownership with the manager. But it can also be - * used anywhere that needs to make an Actor that needs to be in the - * Manager for a given period of time. A good example of this is anything - * that needs Actor commands to work on an actor that is made in a given - * scope. One main place where this happens is in the Actor asset processor - * code. - */ - class AutoRegisteredActor - { - public: - AutoRegisteredActor() = default; - - template - AutoRegisteredActor(AZStd::shared_ptr actor) - : m_actor(AZStd::move(actor)) - { - Register(m_actor); - } - template - AutoRegisteredActor(AZStd::unique_ptr actor) - : m_actor(AZStd::move(actor)) - { - Register(m_actor); - } - - // This class is not copyable, because a given actor cannot be - // registered with the manager multiple times - AutoRegisteredActor(const AutoRegisteredActor&) = delete; - AutoRegisteredActor& operator=(const AutoRegisteredActor&) = delete; - - AutoRegisteredActor(AutoRegisteredActor&& other) noexcept - { - *this = AZStd::move(other); - } - - AutoRegisteredActor& operator=(AutoRegisteredActor&& other) noexcept - { - if (this != &other) - { - Unregister(m_actor); - m_actor = AZStd::move(other.m_actor); - } - return *this; - } - - ~AutoRegisteredActor() - { - Unregister(m_actor); - } - - Actor* operator->() const - { - return m_actor.operator->(); - } - - operator bool() const - { - return static_cast(m_actor); - } - - Actor* get() const - { - return m_actor.get(); - } - - private: - void Register(const AZStd::shared_ptr& actor) - { - if (actor) - { - GetActorManager().RegisterActor(actor); - } - } - - void Unregister(const AZStd::shared_ptr& actor) - { - if (actor) - { - GetActorManager().UnregisterActor(actor); - } - } - - AZStd::shared_ptr m_actor; - }; -} // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.cpp index 2321d7c71b..b385de62be 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.cpp @@ -46,15 +46,10 @@ AZ_POP_DISABLE_WARNING namespace EMStudio { - //-------------------------------------------------------------------------- - // globals - //-------------------------------------------------------------------------- - EMStudioManager* gEMStudioMgr = nullptr; - - //-------------------------------------------------------------------------- // class EMStudioManager //-------------------------------------------------------------------------- + AZ_CLASS_ALLOCATOR_IMPL(EMStudioManager, AZ::SystemAllocator, 0) // constructor EMStudioManager::EMStudioManager(QApplication* app, [[maybe_unused]] int& argc, [[maybe_unused]] char* argv[]) @@ -105,8 +100,9 @@ namespace EMStudio // log some information LogInfo(); - } + AZ::Interface::Register(this); + } // destructor EMStudioManager::~EMStudioManager() @@ -130,6 +126,8 @@ namespace EMStudio delete m_commandManager; AZ::AllocatorInstance::Destroy(); + + AZ::Interface::Unregister(this); } MainWindow* EMStudioManager::GetMainWindow() @@ -422,6 +420,12 @@ namespace EMStudio } + EMStudioManager* EMStudioManager::GetInstance() + { + return AZ::Interface().Get(); + } + + // function to add a gizmo to the manager MCommon::TransformationManipulator* EMStudioManager::AddTransformationManipulator(MCommon::TransformationManipulator* manipulator) { @@ -494,30 +498,48 @@ namespace EMStudio painter.drawPath(path); } - //-------------------------------------------------------------------------- - // class Initializer - //-------------------------------------------------------------------------- - // initialize EMotion Studio - bool Initializer::Init(QApplication* app, int& argc, char* argv[]) + // shortcuts + QApplication* GetApp() { - // do nothing if we already have initialized - if (gEMStudioMgr) - { - return true; - } - - // create the new EMStudio object - gEMStudioMgr = new EMStudioManager(app, argc, argv); - - // return success - return true; + return EMStudioManager::GetInstance()->GetApp(); + } + EMStudioManager* GetManager() + { + return EMStudioManager::GetInstance(); } - - // the shutdown function - void Initializer::Shutdown() + bool HasMainWindow() { - delete gEMStudioMgr; - gEMStudioMgr = nullptr; + return EMStudioManager::GetInstance()->HasMainWindow(); + } + + MainWindow* GetMainWindow() + { + return EMStudioManager::GetInstance()->GetMainWindow(); + } + + PluginManager* GetPluginManager() + { + return EMStudioManager::GetInstance()->GetPluginManager(); + } + + LayoutManager* GetLayoutManager() + { + return EMStudioManager::GetInstance()->GetLayoutManager(); + } + + NotificationWindowManager* GetNotificationWindowManager() + { + return EMStudioManager::GetInstance()->GetNotificationWindowManager(); + } + + MotionEventPresetManager* GetEventPresetManager() + { + return EMStudioManager::GetInstance()->GetEventPresetManger(); + } + + CommandSystem::CommandManager* GetCommandManager() + { + return EMStudioManager::GetInstance()->GetCommandManager(); } } // namespace EMStudio diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.h index 909f0231f3..4c3139b77a 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.h @@ -53,9 +53,10 @@ namespace EMStudio class EMSTUDIO_API EMStudioManager : private EMotionFX::SkeletonOutlinerNotificationBus::Handler { - MCORE_MEMORYOBJECTCATEGORY(EMStudioManager, MCore::MCORE_DEFAULT_ALIGNMENT, MEMCATEGORY_EMSTUDIOSDK) - public: + AZ_RTTI(EMStudio::EMStudioManager, "{D45E95CF-0C7B-44F1-A9D4-99A1E12A5AB5}") + AZ_CLASS_ALLOCATOR_DECL + EMStudioManager(QApplication* app, int& argc, char* argv[]); ~EMStudioManager(); @@ -72,6 +73,9 @@ namespace EMStudio AZStd::string GetRecoverFolder() const; AZStd::string GetAutosavesFolder() const; + // Singleton pattern + static EMStudioManager* GetInstance(); + // text rendering helper function static void RenderText(QPainter& painter, const QString& text, const QColor& textColor, const QFont& font, const QFontMetrics& fontMetrics, Qt::Alignment textAlignment, const QRect& rect); @@ -150,34 +154,17 @@ namespace EMStudio void OnRemoveCommand(size_t historyIndex) override { MCORE_UNUSED(historyIndex); } void OnSetCurrentCommand(size_t index) override { MCORE_UNUSED(index); } }; - EventProcessingCallback* m_eventProcessingCallback; + EventProcessingCallback* m_eventProcessingCallback = nullptr; }; - - /** - * - * - * - */ - class EMSTUDIO_API Initializer - { - public: - static bool MCORE_CDECL Init(QApplication* app, int& argc, char* argv[]); - static void MCORE_CDECL Shutdown(); - }; - - - // the global manager - extern EMSTUDIO_API EMStudioManager* gEMStudioMgr; - - // shortcuts - MCORE_INLINE QApplication* GetApp() { return gEMStudioMgr->GetApp(); } - MCORE_INLINE EMStudioManager* GetManager() { return gEMStudioMgr; } - MCORE_INLINE bool HasMainWindow() { return gEMStudioMgr->HasMainWindow(); } - MCORE_INLINE MainWindow* GetMainWindow() { return gEMStudioMgr->GetMainWindow(); } - MCORE_INLINE PluginManager* GetPluginManager() { return gEMStudioMgr->GetPluginManager(); } - MCORE_INLINE LayoutManager* GetLayoutManager() { return gEMStudioMgr->GetLayoutManager(); } - MCORE_INLINE NotificationWindowManager* GetNotificationWindowManager() { return gEMStudioMgr->GetNotificationWindowManager(); } - MCORE_INLINE MotionEventPresetManager* GetEventPresetManager() { return gEMStudioMgr->GetEventPresetManger(); } - MCORE_INLINE CommandSystem::CommandManager* GetCommandManager() { return gEMStudioMgr->GetCommandManager(); } + // Shortcuts + QApplication* GetApp(); + EMStudioManager* GetManager(); + bool HasMainWindow(); + MainWindow* GetMainWindow(); + PluginManager* GetPluginManager(); + LayoutManager* GetLayoutManager(); + NotificationWindowManager* GetNotificationWindowManager(); + MotionEventPresetManager* GetEventPresetManager(); + CommandSystem::CommandManager* GetCommandManager(); } // namespace EMStudio diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/FileManager.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/FileManager.cpp index 2d65a228b7..17438dd59a 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/FileManager.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/FileManager.cpp @@ -112,10 +112,6 @@ namespace EMStudio for (size_t i = 0; i < actorCount; ++i) { EMotionFX::Actor* actor = EMotionFX::GetActorManager().GetActor(i); - if (actor->GetIsOwnedByRuntime()) - { - continue; - } if (AzFramework::StringFunc::Equal(filename, actor->GetFileName())) { diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.cpp index 002634ea90..b75fb71060 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.cpp @@ -1792,11 +1792,6 @@ namespace EMStudio { EMotionFX::Actor* actor = selectionList.GetActorInstance(i)->GetActor(); - if (actor->GetIsOwnedByRuntime()) - { - continue; - } - if (AZStd::find(savingActors.begin(), savingActors.end(), actor) == savingActors.end()) { savingActors.push_back(actor); diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.h index 585101f7d2..1aa8676352 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.h @@ -10,9 +10,9 @@ #if !defined(Q_MOC_RUN) #include -#include -#include -#include +#include +#include +#include #include #include #include diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderPlugin.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderPlugin.cpp index db0c355002..c74cb3cb0f 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderPlugin.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderPlugin.cpp @@ -389,7 +389,7 @@ namespace EMStudio // get the current actor and the number of clones EMotionFX::Actor* actor = EMotionFX::GetActorManager().GetActor(i); - if (actor->GetIsOwnedByRuntime() || !actor->IsReady()) + if (!actor->IsReady()) { continue; } @@ -421,7 +421,7 @@ namespace EMStudio // At this point the render actor could point to an already deleted actor. // In case the actor got deleted we might get an unexpected flag as result. - if (!found || (found && actor->GetIsOwnedByRuntime()) || (!actor->IsReady())) + if (!found || (!actor->IsReady())) { DestroyEMStudioActor(actor); } diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderViewWidget.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderViewWidget.cpp index 93a6dd3019..fe8fb61f02 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderViewWidget.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderViewWidget.cpp @@ -155,12 +155,12 @@ namespace EMStudio cameraMenu->addAction("Reset Camera", [this]() { this->OnResetCamera(); }); QAction* showSelectedAction = cameraMenu->addAction("Show Selected", this, &RenderViewWidget::OnShowSelected); - showSelectedAction->setShortcut(Qt::Key_S); + showSelectedAction->setShortcut(QKeySequence(Qt::Key_S + Qt::SHIFT)); GetMainWindow()->GetShortcutManager()->RegisterKeyboardShortcut(showSelectedAction, RenderPlugin::s_renderWindowShortcutGroupName, true); addAction(showSelectedAction); QAction* showEntireSceneAction = cameraMenu->addAction("Show Entire Scene", this, &RenderViewWidget::OnShowEntireScene); - showEntireSceneAction->setShortcut(Qt::Key_A); + showEntireSceneAction->setShortcut(QKeySequence(Qt::Key_A + Qt::SHIFT)); GetMainWindow()->GetShortcutManager()->RegisterKeyboardShortcut(showEntireSceneAction, RenderPlugin::s_renderWindowShortcutGroupName, true); addAction(showEntireSceneAction); diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/ResetSettingsDialog.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/ResetSettingsDialog.cpp index 2f45a89ea2..5c15f4b6be 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/ResetSettingsDialog.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/ResetSettingsDialog.cpp @@ -65,8 +65,7 @@ namespace EMStudio m_actorCheckbox = new QCheckBox("Actors"); m_actorCheckbox->setObjectName("EMFX.ResetSettingsDialog.Actors"); - const bool hasActors = HasEntityInEditor( - EMotionFX::GetActorManager(), &EMotionFX::ActorManager::GetNumActors, &EMotionFX::ActorManager::GetActor); + const bool hasActors = EMotionFX::GetActorManager().GetNumActors() > 0; m_actorCheckbox->setChecked(hasActors); m_actorCheckbox->setDisabled(!hasActors); diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/NodeWindowPlugin.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/NodeWindowPlugin.cpp index 6b7beb20de..4629e8dc54 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/NodeWindowPlugin.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/NodeWindowPlugin.cpp @@ -327,7 +327,16 @@ namespace EMStudio void NodeWindowPlugin::OnActorReady([[maybe_unused]] EMotionFX::Actor* actor) { - ReInit(); + m_reinitRequested = true; + } + + void NodeWindowPlugin::ProcessFrame([[maybe_unused]] float timePassedInSeconds) + { + if (m_reinitRequested) + { + ReInit(); + m_reinitRequested = false; + } } //----------------------------------------------------------------------------------------- diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/NodeWindowPlugin.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/NodeWindowPlugin.h index 157486df10..59c9f78719 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/NodeWindowPlugin.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeWindow/NodeWindowPlugin.h @@ -60,6 +60,8 @@ namespace EMStudio EMStudioPlugin* Clone() override; void ReInit(); + void ProcessFrame(float timePassedInSeconds) override; + public slots: void OnNodeChanged(); void VisibilityChanged(bool isVisible); @@ -87,5 +89,8 @@ namespace EMStudio AZStd::unique_ptr m_actorInfo; AZStd::unique_ptr m_nodeInfo; + + // Use this flag to defer the reinit function to main thread. + bool m_reinitRequested = false; }; } // namespace EMStudio diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/SceneManager/ActorsWindow.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/SceneManager/ActorsWindow.cpp index 5012ee2578..c1e35967ec 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/SceneManager/ActorsWindow.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/SceneManager/ActorsWindow.cpp @@ -123,12 +123,6 @@ namespace EMStudio continue; } - // ignore engine actors - if (actor->GetIsOwnedByRuntime()) - { - continue; - } - // create a tree item for the new attachment QTreeWidgetItem* newItem = new QTreeWidgetItem(m_treeWidget); diff --git a/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake b/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake index b12cbe102f..9947850471 100644 --- a/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake +++ b/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake @@ -25,7 +25,6 @@ set(FILES Source/AttachmentNode.h Source/AttachmentSkin.cpp Source/AttachmentSkin.h - Source/AutoRegisteredActor.h Source/BaseObject.cpp Source/BaseObject.h Source/CompressedKeyFrames.h diff --git a/Gems/EMotionFX/Code/Include/Integration/ActorComponentBus.h b/Gems/EMotionFX/Code/Include/Integration/ActorComponentBus.h index 6000873db1..4161b3c77d 100644 --- a/Gems/EMotionFX/Code/Include/Integration/ActorComponentBus.h +++ b/Gems/EMotionFX/Code/Include/Integration/ActorComponentBus.h @@ -16,7 +16,7 @@ #include #include #include - +#include namespace EMotionFX { @@ -96,6 +96,9 @@ namespace EMotionFX /// Returns skinning method used by the actor. virtual SkinningMethod GetSkinningMethod() const = 0; + // Use this to alter the actor asset. + virtual void SetActorAsset(AZ::Data::Asset actorAsset) = 0; + static const size_t s_invalidJointIndex = std::numeric_limits::max(); }; diff --git a/Gems/EMotionFX/Code/Include/Integration/AnimationBus.h b/Gems/EMotionFX/Code/Include/Integration/AnimationBus.h index 1b9eb55216..474ac1b6d5 100644 --- a/Gems/EMotionFX/Code/Include/Integration/AnimationBus.h +++ b/Gems/EMotionFX/Code/Include/Integration/AnimationBus.h @@ -46,6 +46,9 @@ namespace EMotionFX public: static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; + + // Use this bus to register custom EMotionFX plugin. + virtual void OnRegisterPlugin() = 0; }; using SystemNotificationBus = AZ::EBus; diff --git a/Gems/EMotionFX/Code/Source/Integration/Assets/ActorAsset.cpp b/Gems/EMotionFX/Code/Source/Integration/Assets/ActorAsset.cpp index 5082d4b739..64117fa814 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Assets/ActorAsset.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/Assets/ActorAsset.cpp @@ -6,7 +6,6 @@ * */ -#include #include #include #include @@ -64,8 +63,7 @@ namespace EMotionFX &actorSettings, ""); - // Set the is owned by runtime flag before finalizing the actor, as that uses the flag already. - assetData->m_emfxActor->SetIsOwnedByRuntime(true); + assetData->m_emfxActor->SetFileName(asset.GetHint().c_str()); assetData->m_emfxActor->Finalize(); // Clear out the EMFX raw asset data. diff --git a/Gems/EMotionFX/Code/Source/Integration/Assets/ActorAsset.h b/Gems/EMotionFX/Code/Source/Integration/Assets/ActorAsset.h index 8732c6a448..4b13603ed5 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Assets/ActorAsset.h +++ b/Gems/EMotionFX/Code/Source/Integration/Assets/ActorAsset.h @@ -15,7 +15,6 @@ #include #include -#include namespace EMotionFX @@ -58,7 +57,7 @@ namespace EMotionFX void InitRenderActor(); private: - AutoRegisteredActor m_emfxActor; ///< Pointer to shared EMotionFX actor + AZStd::shared_ptr m_emfxActor; AZStd::unique_ptr m_renderActor; }; @@ -81,6 +80,8 @@ namespace EMotionFX const char* GetBrowserIcon() const override; }; } // namespace Integration + + using ActorAssetData = AZ::Data::Asset; } // namespace EMotionFX namespace AZ diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.h b/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.h index b376fa891d..15d9736f34 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.h +++ b/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.h @@ -121,6 +121,7 @@ namespace EMotionFX void SetRenderCharacter(bool enable) override; bool GetRenderActorVisible() const override; SkinningMethod GetSkinningMethod() const override; + void SetActorAsset(AZ::Data::Asset actorAsset) override; ////////////////////////////////////////////////////////////////////////// // ActorComponentNotificationBus::Handler @@ -178,8 +179,6 @@ namespace EMotionFX void OnAssetReloaded(AZ::Data::Asset asset) override; bool IsPhysicsSceneSimulationFinishEventConnected() const; - - void SetActorAsset(AZ::Data::Asset actorAsset); AZ::Data::Asset GetActorAsset() const { return m_configuration.m_actorAsset; } private: diff --git a/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.h b/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.h index e8f76bdd49..1d682b47d4 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.h +++ b/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.h @@ -60,6 +60,7 @@ namespace EMotionFX bool GetRenderActorVisible() const override; size_t GetNumJoints() const override; SkinningMethod GetSkinningMethod() const override; + void SetActorAsset(AZ::Data::Asset actorAsset) override; // EditorActorComponentRequestBus overrides ... const AZ::Data::AssetId& GetActorAssetId() override; @@ -79,8 +80,6 @@ namespace EMotionFX void OnAssetReady(AZ::Data::Asset asset) override; void OnAssetReloaded(AZ::Data::Asset asset) override; - void SetActorAsset(AZ::Data::Asset actorAsset); - // BoundsRequestBus overrides ... AZ::Aabb GetWorldBounds() override; AZ::Aabb GetLocalBounds() override; diff --git a/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp b/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp index 08e99f97d0..38af4232ba 100644 --- a/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,7 @@ #include #include +#include #include #include #include @@ -69,7 +71,6 @@ # include # include # include -# include # include # include // EMStudio plugins @@ -528,7 +529,7 @@ namespace EMotionFX if (EMStudio::GetManager()) { - EMStudio::Initializer::Shutdown(); + m_emstudioManager.reset(); MysticQt::Initializer::Shutdown(); } @@ -798,6 +799,8 @@ namespace EMotionFX pluginManager->RegisterPlugin(new EMotionFX::RagdollNodeInspectorPlugin()); pluginManager->RegisterPlugin(new EMotionFX::ClothJointInspectorPlugin()); pluginManager->RegisterPlugin(new EMotionFX::SimulatedObjectWidget()); + + SystemNotificationBus::Broadcast(&SystemNotificationBus::Events::OnRegisterPlugin); } ////////////////////////////////////////////////////////////////////////// @@ -813,7 +816,7 @@ namespace EMotionFX char** argv = nullptr; MysticQt::Initializer::Init("", editorAssetsPath.c_str()); - EMStudio::Initializer::Init(qApp, argc, argv); + m_emstudioManager = AZStd::make_unique(qApp, argc, argv); InitializeEMStudioPlugins(); diff --git a/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.h b/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.h index 5e30820ca3..3ef626c947 100644 --- a/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.h +++ b/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.h @@ -24,6 +24,7 @@ # include # include # include +# include #endif // EMOTIONFXANIMATION_EDITOR namespace AZ @@ -126,6 +127,10 @@ namespace EMotionFX AZStd::vector > m_assetHandlers; AZStd::unique_ptr m_eventHandler; AZStd::unique_ptr m_renderBackendManager; + +#if defined(EMOTIONFXANIMATION_EDITOR) + AZStd::unique_ptr m_emstudioManager; +#endif // EMOTIONFXANIMATION_EDITOR }; } } diff --git a/Gems/EMotionFX/Code/Tests/ActorFixture.cpp b/Gems/EMotionFX/Code/Tests/ActorFixture.cpp index e77df103e0..33c26ca11e 100644 --- a/Gems/EMotionFX/Code/Tests/ActorFixture.cpp +++ b/Gems/EMotionFX/Code/Tests/ActorFixture.cpp @@ -10,12 +10,15 @@ #include #include #include +#include #include #include #include #include #include +#include + namespace EMotionFX { @@ -23,8 +26,9 @@ namespace EMotionFX { SystemComponentFixture::SetUp(); - m_actor = ActorFactory::CreateAndInit(); - m_actorInstance = ActorInstance::Create(m_actor.get()); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + m_actorAsset = TestActorAssets::CreateActorAssetAndRegister(actorAssetId); + m_actorInstance = ActorInstance::Create(GetActor()); } void ActorFixture::TearDown() @@ -35,6 +39,7 @@ namespace EMotionFX m_actorInstance = nullptr; } + GetEMotionFX().GetActorManager()->UnregisterAllActors(); SystemComponentFixture::TearDown(); } @@ -71,7 +76,7 @@ namespace EMotionFX AZ::ObjectStream::FilterDescriptor loadFilter(nullptr, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES); SimulatedObjectSetup* setup = AZ::Utils::LoadObjectFromBuffer(data.data(), data.size(), serializeContext, loadFilter); - setup->InitAfterLoad(m_actor.get()); + setup->InitAfterLoad(GetActor()); return setup; } @@ -80,4 +85,10 @@ namespace EMotionFX { return { "Bip01__pelvis", "l_upLeg", "l_loLeg", "l_ankle" }; } + + + Actor* ActorFixture::GetActor() const + { + return m_actorAsset->GetActor(); + } } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/Tests/ActorFixture.h b/Gems/EMotionFX/Code/Tests/ActorFixture.h index 9fee056292..569d55cf47 100644 --- a/Gems/EMotionFX/Code/Tests/ActorFixture.h +++ b/Gems/EMotionFX/Code/Tests/ActorFixture.h @@ -9,8 +9,7 @@ #pragma once #include "SystemComponentFixture.h" -#include - +#include namespace EMotionFX { @@ -31,7 +30,9 @@ namespace EMotionFX AZStd::vector GetTestJointNames() const; protected: - AutoRegisteredActor m_actor{}; + Actor* GetActor() const; + + AZ::Data::Asset m_actorAsset; ActorInstance* m_actorInstance = nullptr; }; } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/Tests/AdditiveMotionSamplingTests.cpp b/Gems/EMotionFX/Code/Tests/AdditiveMotionSamplingTests.cpp index 4171598801..114d5c08fb 100644 --- a/Gems/EMotionFX/Code/Tests/AdditiveMotionSamplingTests.cpp +++ b/Gems/EMotionFX/Code/Tests/AdditiveMotionSamplingTests.cpp @@ -26,7 +26,7 @@ namespace EMotionFX public: void CreateSubMotionLikeBindPose(const std::string& name) { - const Skeleton* skeleton = m_actor->GetSkeleton(); + const Skeleton* skeleton = GetActor()->GetSkeleton(); size_t jointIndex = InvalidIndex; const Node* node = skeleton->FindNodeAndIndexByName(name.c_str(), jointIndex); ASSERT_NE(node, nullptr); @@ -40,7 +40,7 @@ namespace EMotionFX void CreateSubMotion(const std::string& name, const Transform& transform) { // Find and store the joint index. - const Skeleton* skeleton = m_actor->GetSkeleton(); + const Skeleton* skeleton = GetActor()->GetSkeleton(); size_t jointIndex = InvalidIndex; const Node* node = skeleton->FindNodeAndIndexByName(name.c_str(), jointIndex); ASSERT_NE(node, nullptr); @@ -55,7 +55,7 @@ namespace EMotionFX ActorFixture::SetUp(); // Get the joint that isn't in the motion data. - Node* footNode = m_actor->GetSkeleton()->FindNodeAndIndexByName("l_ball", m_footIndex); + Node* footNode = GetActor()->GetSkeleton()->FindNodeAndIndexByName("l_ball", m_footIndex); ASSERT_NE(footNode, nullptr); ASSERT_NE(m_footIndex, InvalidIndex32); @@ -98,7 +98,7 @@ namespace EMotionFX TEST_F(MotionSamplingFixture, SampleAdditiveJoint) { - const Skeleton* skeleton = m_actor->GetSkeleton(); + const Skeleton* skeleton = GetActor()->GetSkeleton(); // Sample the joints that exist in our actor skeleton as well as inside the motion data. const Pose* bindPose = m_actorInstance->GetTransformData()->GetBindPose(); @@ -106,7 +106,7 @@ namespace EMotionFX { // Sample the motion. Transform transform = Transform::CreateZero(); // Set all to Zero, not identity as this methods might return identity and we want to verify that. - m_motion->CalcNodeTransform(m_motionInstance, &transform, m_actor.get(), skeleton->GetNode(jointIndex), /*timeValue=*/0.0f, /*enableRetargeting=*/false); + m_motion->CalcNodeTransform(m_motionInstance, &transform, GetActor(), skeleton->GetNode(jointIndex), /*timeValue=*/0.0f, /*enableRetargeting=*/false); const Transform& bindTransform = bindPose->GetLocalSpaceTransform(jointIndex); EXPECT_THAT(transform, IsClose(bindTransform)); @@ -114,7 +114,7 @@ namespace EMotionFX // Sample the motion for the foot node. Transform footTransform = Transform::CreateZero(); // Set all to Zero, not identity as this methods might return identity and we want to verify that. - m_motion->CalcNodeTransform(m_motionInstance, &footTransform, m_actor.get(), skeleton->GetNode(m_footIndex), /*timeValue=*/0.0f, /*enableRetargeting=*/false); + m_motion->CalcNodeTransform(m_motionInstance, &footTransform, GetActor(), skeleton->GetNode(m_footIndex), /*timeValue=*/0.0f, /*enableRetargeting=*/false); // Make sure we get an identity transform back as we try to sample a node that doesn't have a submotion in an additive motion. EXPECT_THAT(footTransform, IsClose(Transform::CreateIdentity())); @@ -125,7 +125,7 @@ namespace EMotionFX // Make sure we do not get an identity transform back now that it is a non-additive motion. footTransform.Zero(); // Set all to Zero, not identity as this methods might return identity and we want to verify that. const Transform& expectedFootTransform = m_actorInstance->GetTransformData()->GetCurrentPose()->GetLocalSpaceTransform(m_footIndex); - m_motion->CalcNodeTransform(m_motionInstance, &footTransform, m_actor.get(), skeleton->GetNode(m_footIndex), /*timeValue=*/0.0f, /*enableRetargeting=*/false); + m_motion->CalcNodeTransform(m_motionInstance, &footTransform, GetActor(), skeleton->GetNode(m_footIndex), /*timeValue=*/0.0f, /*enableRetargeting=*/false); EXPECT_THAT(footTransform, IsClose(expectedFootTransform)); } @@ -134,7 +134,7 @@ namespace EMotionFX // Sample a pose from the motion. Pose pose; pose.LinkToActorInstance(m_actorInstance); - pose.InitFromBindPose(m_actor.get()); + pose.InitFromBindPose(GetActor()); pose.Zero(); m_motion->Update(&pose, &pose, m_motionInstance); diff --git a/Gems/EMotionFX/Code/Tests/AnimGraphDeferredInitTests.cpp b/Gems/EMotionFX/Code/Tests/AnimGraphDeferredInitTests.cpp index 0449005659..4448deff27 100644 --- a/Gems/EMotionFX/Code/Tests/AnimGraphDeferredInitTests.cpp +++ b/Gems/EMotionFX/Code/Tests/AnimGraphDeferredInitTests.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/Gems/EMotionFX/Code/Tests/BlendTreeRagdollNodeTests.cpp b/Gems/EMotionFX/Code/Tests/BlendTreeRagdollNodeTests.cpp index a01d333e95..4608917523 100644 --- a/Gems/EMotionFX/Code/Tests/BlendTreeRagdollNodeTests.cpp +++ b/Gems/EMotionFX/Code/Tests/BlendTreeRagdollNodeTests.cpp @@ -105,7 +105,7 @@ namespace EMotionFX TEST_P(RagdollRootNodeFixture, RagdollRootNodeIsSimulatedTests) { - Physics::RagdollConfiguration& ragdollConfig = m_actor->GetPhysicsSetup()->GetRagdollConfig(); + Physics::RagdollConfiguration& ragdollConfig = GetActor()->GetPhysicsSetup()->GetRagdollConfig(); AZStd::vector& ragdollNodes = ragdollConfig.m_nodes; const RagdollRootNodeParam& param = GetParam(); const AZStd::string ragdollRootNodeName = param.m_ragdollRootNode.c_str(); diff --git a/Gems/EMotionFX/Code/Tests/ColliderCommandTests.cpp b/Gems/EMotionFX/Code/Tests/ColliderCommandTests.cpp index 6314253eee..a6cadc5c2f 100644 --- a/Gems/EMotionFX/Code/Tests/ColliderCommandTests.cpp +++ b/Gems/EMotionFX/Code/Tests/ColliderCommandTests.cpp @@ -24,13 +24,13 @@ namespace EMotionFX CommandSystem::CommandManager commandManager; MCore::CommandGroup commandGroup; - const AZ::u32 actorId = m_actor->GetID(); + const AZ::u32 actorId = GetActor()->GetID(); const AZStd::vector jointNames = GetTestJointNames(); const size_t jointCount = jointNames.size(); // 1. Add colliders - const AZStd::string serializedBeforeAdd = SerializePhysicsSetup(m_actor.get()); + const AZStd::string serializedBeforeAdd = SerializePhysicsSetup(GetActor()); for (const AZStd::string& jointName : jointNames) { CommandColliderHelpers::AddCollider(actorId, jointName, PhysicsSetup::HitDetection, azrtti_typeid(), &commandGroup); @@ -39,23 +39,27 @@ namespace EMotionFX } EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)); - const AZStd::string serializedAfterAdd = SerializePhysicsSetup(m_actor.get()); - EXPECT_EQ(jointCount * 3, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection)); - EXPECT_EQ(jointCount, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection, /*ignoreShapeType*/false, Physics::ShapeType::Box)); + const AZStd::string serializedAfterAdd = SerializePhysicsSetup(GetActor()); + EXPECT_EQ(jointCount * 3, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection)); + EXPECT_EQ( + jointCount, + PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection, /*ignoreShapeType*/ false, Physics::ShapeType::Box)); EXPECT_TRUE(commandManager.Undo(result)); - EXPECT_EQ(0, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection)); - EXPECT_EQ(serializedBeforeAdd, SerializePhysicsSetup(m_actor.get())); + EXPECT_EQ(0, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection)); + EXPECT_EQ(serializedBeforeAdd, SerializePhysicsSetup(GetActor())); EXPECT_TRUE(commandManager.Redo(result)); - EXPECT_EQ(jointCount * 3, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection)); - EXPECT_EQ(jointCount, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection, /*ignoreShapeType*/false, Physics::ShapeType::Box)); - EXPECT_EQ(serializedAfterAdd, SerializePhysicsSetup(m_actor.get())); + EXPECT_EQ(jointCount * 3, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection)); + EXPECT_EQ( + jointCount, + PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection, /*ignoreShapeType*/ false, Physics::ShapeType::Box)); + EXPECT_EQ(serializedAfterAdd, SerializePhysicsSetup(GetActor())); // 2. Remove colliders commandGroup.RemoveAllCommands(); - const AZStd::string serializedBeforeRemove = SerializePhysicsSetup(m_actor.get()); + const AZStd::string serializedBeforeRemove = SerializePhysicsSetup(GetActor()); size_t colliderIndexToRemove = 1; for (const AZStd::string& jointName : jointNames) @@ -64,18 +68,24 @@ namespace EMotionFX } EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)); - const AZStd::string serializedAfterRemove = SerializePhysicsSetup(m_actor.get()); - EXPECT_EQ(jointCount * 2, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection)); - EXPECT_EQ(0, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection, /*ignoreShapeType*/false, Physics::ShapeType::Capsule)); + const AZStd::string serializedAfterRemove = SerializePhysicsSetup(GetActor()); + EXPECT_EQ(jointCount * 2, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection)); + EXPECT_EQ( + 0, + PhysicsSetupUtils::CountColliders( + GetActor(), PhysicsSetup::HitDetection, /*ignoreShapeType*/ false, Physics::ShapeType::Capsule)); EXPECT_TRUE(commandManager.Undo(result)); - EXPECT_EQ(jointCount * 3, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection)); - EXPECT_EQ(serializedBeforeRemove, SerializePhysicsSetup(m_actor.get())); + EXPECT_EQ(jointCount * 3, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection)); + EXPECT_EQ(serializedBeforeRemove, SerializePhysicsSetup(GetActor())); EXPECT_TRUE(commandManager.Redo(result)); - EXPECT_EQ(jointCount * 2, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection)); - EXPECT_EQ(0, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection, /*ignoreShapeType*/false, Physics::ShapeType::Capsule)); - EXPECT_EQ(serializedAfterRemove, SerializePhysicsSetup(m_actor.get())); + EXPECT_EQ(jointCount * 2, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection)); + EXPECT_EQ( + 0, + PhysicsSetupUtils::CountColliders( + GetActor(), PhysicsSetup::HitDetection, /*ignoreShapeType*/ false, Physics::ShapeType::Capsule)); + EXPECT_EQ(serializedAfterRemove, SerializePhysicsSetup(GetActor())); } TEST_F(ColliderCommandTests, AddRemove1000Colliders) @@ -84,11 +94,11 @@ namespace EMotionFX CommandSystem::CommandManager commandManager; MCore::CommandGroup commandGroup; - const AZ::u32 actorId = m_actor->GetID(); + const AZ::u32 actorId = GetActor()->GetID(); const AZStd::string jointName = "Bip01__pelvis"; // 1. Add colliders - const AZStd::string serializedBeforeAdd = SerializePhysicsSetup(m_actor.get()); + const AZStd::string serializedBeforeAdd = SerializePhysicsSetup(GetActor()); const size_t colliderCount = 1000; for (AZ::u32 i = 0; i < colliderCount; ++i) { @@ -96,51 +106,51 @@ namespace EMotionFX } EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)); - const AZStd::string serializedAfterAdd = SerializePhysicsSetup(m_actor.get()); - EXPECT_EQ(colliderCount, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection)); - EXPECT_EQ(colliderCount, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection, /*ignoreShapeType*/false, Physics::ShapeType::Box)); + const AZStd::string serializedAfterAdd = SerializePhysicsSetup(GetActor()); + EXPECT_EQ(colliderCount, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection)); + EXPECT_EQ(colliderCount, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection, /*ignoreShapeType*/false, Physics::ShapeType::Box)); EXPECT_TRUE(commandManager.Undo(result)); - EXPECT_EQ(0, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection)); - EXPECT_EQ(serializedBeforeAdd, SerializePhysicsSetup(m_actor.get())); + EXPECT_EQ(0, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection)); + EXPECT_EQ(serializedBeforeAdd, SerializePhysicsSetup(GetActor())); EXPECT_TRUE(commandManager.Redo(result)); - EXPECT_EQ(colliderCount, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection)); - EXPECT_EQ(colliderCount, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection, /*ignoreShapeType*/false, Physics::ShapeType::Box)); - EXPECT_EQ(serializedAfterAdd, SerializePhysicsSetup(m_actor.get())); + EXPECT_EQ(colliderCount, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection)); + EXPECT_EQ(colliderCount, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection, /*ignoreShapeType*/false, Physics::ShapeType::Box)); + EXPECT_EQ(serializedAfterAdd, SerializePhysicsSetup(GetActor())); // 2. Clear colliders commandGroup.RemoveAllCommands(); - const AZStd::string serializedBeforeRemove = SerializePhysicsSetup(m_actor.get()); + const AZStd::string serializedBeforeRemove = SerializePhysicsSetup(GetActor()); CommandColliderHelpers::ClearColliders(actorId, jointName, PhysicsSetup::HitDetection, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)); - const AZStd::string serializedAfterRemove = SerializePhysicsSetup(m_actor.get()); - EXPECT_EQ(0, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection)); - EXPECT_EQ(0, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection, /*ignoreShapeType*/false, Physics::ShapeType::Box)); + const AZStd::string serializedAfterRemove = SerializePhysicsSetup(GetActor()); + EXPECT_EQ(0, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection)); + EXPECT_EQ(0, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection, /*ignoreShapeType*/false, Physics::ShapeType::Box)); EXPECT_TRUE(commandManager.Undo(result)); - EXPECT_EQ(colliderCount, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection)); - EXPECT_EQ(serializedBeforeRemove, SerializePhysicsSetup(m_actor.get())); + EXPECT_EQ(colliderCount, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection)); + EXPECT_EQ(serializedBeforeRemove, SerializePhysicsSetup(GetActor())); EXPECT_TRUE(commandManager.Redo(result)); - EXPECT_EQ(0, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection)); - EXPECT_EQ(0, PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::HitDetection, /*ignoreShapeType*/false, Physics::ShapeType::Box)); - EXPECT_EQ(serializedAfterRemove, SerializePhysicsSetup(m_actor.get())); + EXPECT_EQ(0, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection)); + EXPECT_EQ(0, PhysicsSetupUtils::CountColliders(GetActor(), PhysicsSetup::HitDetection, /*ignoreShapeType*/false, Physics::ShapeType::Box)); + EXPECT_EQ(serializedAfterRemove, SerializePhysicsSetup(GetActor())); } TEST_F(ColliderCommandTests, AutoSizingColliders) { CommandSystem::CommandManager commandManager; - const AZ::u32 actorId = m_actor->GetID(); + const AZ::u32 actorId = GetActor()->GetID(); const AZStd::vector jointNames = GetTestJointNames(); ASSERT_TRUE(jointNames.size() > 0) << "The joint names test data needs at least one joint for this test."; const AZStd::string& jointName = jointNames[0]; CommandColliderHelpers::AddCollider(actorId, jointName, PhysicsSetup::HitDetection, azrtti_typeid()); - const AZStd::shared_ptr& physicsSetup = m_actor->GetPhysicsSetup(); + const AZStd::shared_ptr& physicsSetup = GetActor()->GetPhysicsSetup(); Physics::CharacterColliderConfiguration* colliderConfig = physicsSetup->GetColliderConfigByType(PhysicsSetup::HitDetection); EXPECT_NE(colliderConfig, nullptr) << "Collider config should be valid after we added a collider to it."; @@ -184,11 +194,11 @@ namespace EMotionFX const PhysicsSetup::ColliderConfigType m_configType = PhysicsSetup::ColliderConfigType::HitDetection; // Add collider to the given joint first. - const AZStd::shared_ptr& physicsSetup = m_actor->GetPhysicsSetup(); - EXPECT_TRUE(CommandColliderHelpers::AddCollider(m_actor->GetID(), m_jointName, m_configType, param.m_shapeType)); + const AZStd::shared_ptr& physicsSetup = GetActor()->GetPhysicsSetup(); + EXPECT_TRUE(CommandColliderHelpers::AddCollider(GetActor()->GetID(), m_jointName, m_configType, param.m_shapeType)); Physics::CharacterColliderConfiguration* characterColliderConfig = physicsSetup->GetColliderConfigByType(m_configType); ASSERT_TRUE(characterColliderConfig != nullptr); - Physics::CharacterColliderNodeConfiguration* nodeConfig = CommandColliderHelpers::GetCreateNodeConfig(m_actor.get(), m_jointName, *characterColliderConfig, result); + Physics::CharacterColliderNodeConfiguration* nodeConfig = CommandColliderHelpers::GetCreateNodeConfig(GetActor(), m_jointName, *characterColliderConfig, result); ASSERT_TRUE(nodeConfig != nullptr); EXPECT_EQ(nodeConfig->m_shapes.size(), 1); @@ -200,7 +210,8 @@ namespace EMotionFX // Create the adjust collider command and using the data from the test parameter. MCore::Command* orgCommand = CommandSystem::GetCommandManager()->FindCommand(CommandAdjustCollider::s_commandName); - CommandAdjustCollider* command = aznew CommandAdjustCollider(m_actor->GetID(), m_jointName, m_configType, /*colliderIndex=*/0, orgCommand); + CommandAdjustCollider* command = + aznew CommandAdjustCollider(GetActor()->GetID(), m_jointName, m_configType, /*colliderIndex=*/0, orgCommand); command->SetOldIsTrigger(colliderConfig->m_isTrigger); command->SetIsTrigger(param.m_isTrigger); command->SetOldPosition(colliderConfig->m_position); @@ -223,9 +234,9 @@ namespace EMotionFX } // Check execute. - const AZStd::string serializedBeforeExecute = SerializePhysicsSetup(m_actor.get()); + const AZStd::string serializedBeforeExecute = SerializePhysicsSetup(GetActor()); EXPECT_TRUE(CommandSystem::GetCommandManager()->ExecuteCommand(command, result)); - const AZStd::string serializedAfterExecute = SerializePhysicsSetup(m_actor.get()); + const AZStd::string serializedAfterExecute = SerializePhysicsSetup(GetActor()); EXPECT_EQ(colliderConfig->m_isTrigger, param.m_isTrigger); EXPECT_EQ(colliderConfig->m_position, param.m_position); @@ -243,12 +254,12 @@ namespace EMotionFX // Check undo. EXPECT_TRUE(CommandSystem::GetCommandManager()->Undo(result)); - const AZStd::string serializedAfterUndo = SerializePhysicsSetup(m_actor.get()); + const AZStd::string serializedAfterUndo = SerializePhysicsSetup(GetActor()); EXPECT_EQ(serializedAfterUndo, serializedBeforeExecute); // Check redo. EXPECT_TRUE(CommandSystem::GetCommandManager()->Redo(result)); - const AZStd::string serializedAfterRedo = SerializePhysicsSetup(m_actor.get()); + const AZStd::string serializedAfterRedo = SerializePhysicsSetup(GetActor()); EXPECT_EQ(serializedAfterRedo, serializedAfterExecute); } diff --git a/Gems/EMotionFX/Code/Tests/Integration/CanAddActor.cpp b/Gems/EMotionFX/Code/Tests/Integration/CanAddActor.cpp index 31e1f75d29..0c3228567e 100644 --- a/Gems/EMotionFX/Code/Tests/Integration/CanAddActor.cpp +++ b/Gems/EMotionFX/Code/Tests/Integration/CanAddActor.cpp @@ -13,9 +13,11 @@ #include #include +#include +#include #include #include -#include +#include namespace EMotionFX { @@ -33,14 +35,12 @@ namespace EMotionFX ASSERT_EQ(GetActorManager().GetNumActors(), 0); // Load an Actor - const char* actorCmd{ "ImportActor -filename @engroot@/Gems/EMotionFX/Code/Tests/TestAssets/Rin/rin.actor" }; - { - AZStd::string result; - EXPECT_TRUE(CommandSystem::GetCommandManager()->ExecuteCommand(actorCmd, result)) << result.c_str(); - } + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = + TestActorAssets::CreateActorAssetAndRegister(actorAssetId, "Jack"); // Ensure the Actor is correct - ASSERT_TRUE(GetActorManager().FindActorByName("rinActor")); + ASSERT_TRUE(GetActorManager().FindActorByName("Jack")); EXPECT_EQ(GetActorManager().GetNumActors(), 1); } } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/Tests/MotionExtractionBusTests.cpp b/Gems/EMotionFX/Code/Tests/MotionExtractionBusTests.cpp index 170f4d2d75..347d8f93a8 100644 --- a/Gems/EMotionFX/Code/Tests/MotionExtractionBusTests.cpp +++ b/Gems/EMotionFX/Code/Tests/MotionExtractionBusTests.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include diff --git a/Gems/EMotionFX/Code/Tests/MultiThreadSchedulerTests.cpp b/Gems/EMotionFX/Code/Tests/MultiThreadSchedulerTests.cpp index 180da46746..02622ecd67 100644 --- a/Gems/EMotionFX/Code/Tests/MultiThreadSchedulerTests.cpp +++ b/Gems/EMotionFX/Code/Tests/MultiThreadSchedulerTests.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/AnimGraphActivateTests.cpp b/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/AnimGraphActivateTests.cpp index 78cac409a6..dea332b40e 100644 --- a/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/AnimGraphActivateTests.cpp +++ b/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/AnimGraphActivateTests.cpp @@ -19,11 +19,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include namespace EMotionFX @@ -78,7 +80,8 @@ namespace EMotionFX EXPECT_TRUE(CommandSystem::GetCommandManager()->ExecuteCommandGroup(group, commandResult)) << commandResult.c_str(); // Create temp Actor - m_actor = ActorFactory::CreateAndInit(1, "tempActor"); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + m_actorAsset = TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 1, "tempActor"); // Cache some local poitners. m_animGraphPlugin = static_cast(EMStudio::GetPluginManager()->FindActivePlugin(EMStudio::AnimGraphPlugin::CLASS_ID)); @@ -90,6 +93,7 @@ namespace EMotionFX void TearDown() override { + GetEMotionFX().GetActorManager()->UnregisterAllActors(); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); delete m_animGraph; UIFixture::TearDown(); @@ -104,7 +108,7 @@ namespace EMotionFX AZStd::string m_entryNodeName = "testEntry"; AnimGraph* m_animGraph = nullptr; EMStudio::AnimGraphPlugin* m_animGraphPlugin = nullptr; - AutoRegisteredActor m_actor; + AZ::Data::Asset m_actorAsset; }; TEST_F(PopulatedAnimGraphFixture, CanActivateValidGraph) diff --git a/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/AnimGraphModelTests.cpp b/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/AnimGraphModelTests.cpp index 4ffc9e0097..b9b96bb59c 100644 --- a/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/AnimGraphModelTests.cpp +++ b/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/AnimGraphModelTests.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -43,6 +42,7 @@ #include #include #include +#include #include namespace EMotionFX @@ -423,7 +423,10 @@ namespace EMotionFX using testing::Eq; using testing::Not; - AutoRegisteredActor actor = EMotionFX::ActorFactory::CreateAndInit(1); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = + TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 1); + auto motionSet = AZStd::make_unique(); { @@ -432,7 +435,7 @@ namespace EMotionFX } auto* animGraph = EMotionFX::GetAnimGraphManager().FindAnimGraphByID(0); - auto* actorInstance = EMotionFX::ActorInstance::Create(actor.get()); + auto* actorInstance = EMotionFX::ActorInstance::Create(actorAsset->GetActor()); auto* animGraphInstance = EMotionFX::AnimGraphInstance::Create(animGraph, actorInstance, motionSet.get()); actorInstance->SetAnimGraphInstance(animGraphInstance); diff --git a/Gems/EMotionFX/Code/Tests/ProvidesUI/Menus/FileMenu/CanReset.cpp b/Gems/EMotionFX/Code/Tests/ProvidesUI/Menus/FileMenu/CanReset.cpp index d53ddcc924..c374938590 100644 --- a/Gems/EMotionFX/Code/Tests/ProvidesUI/Menus/FileMenu/CanReset.cpp +++ b/Gems/EMotionFX/Code/Tests/ProvidesUI/Menus/FileMenu/CanReset.cpp @@ -24,12 +24,11 @@ #include #include -#include #include #include +#include #include - namespace EMotionFX { @@ -58,8 +57,10 @@ namespace EMotionFX ASSERT_EQ(GetMotionManager().GetNumMotions(), 0) << "Expected exactly zero motions"; // Create Actor, AnimGraph, Motionset and Motion - AutoRegisteredActor actor = ActorFactory::CreateAndInit(2, "SampleActor"); - ActorInstance::Create(actor.get()); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = + TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 2, "SampleActor"); + ActorInstance::Create(actorAsset->GetActor()); { AZStd::string result; ASSERT_TRUE(CommandSystem::GetCommandManager()->ExecuteCommand(createAnimGraphCmd, result)) << result.c_str(); diff --git a/Gems/EMotionFX/Code/Tests/ProvidesUI/Ragdoll/CanCopyPasteColliders.cpp b/Gems/EMotionFX/Code/Tests/ProvidesUI/Ragdoll/CanCopyPasteColliders.cpp index 4f43e7dae5..17f07b2180 100644 --- a/Gems/EMotionFX/Code/Tests/ProvidesUI/Ragdoll/CanCopyPasteColliders.cpp +++ b/Gems/EMotionFX/Code/Tests/ProvidesUI/Ragdoll/CanCopyPasteColliders.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include namespace EMotionFX @@ -79,7 +80,11 @@ namespace EMotionFX TEST_F(CopyPasteRagdollCollidersFixture, CanCopyCollider) #endif // AZ_TRAIT_DISABLE_FAILED_EMOTION_FX_EDITOR_TESTS { - AutoRegisteredActor actor{ActorFactory::CreateAndInit(4)}; + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = + TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 4); + const Actor* actor = actorAsset->GetActor(); + const Physics::RagdollConfiguration& ragdollConfig = actor->GetPhysicsSetup()->GetRagdollConfig(); const Physics::CharacterColliderConfiguration& simulatedObjectConfig = actor->GetPhysicsSetup()->GetSimulatedObjectColliderConfig(); @@ -104,8 +109,7 @@ namespace EMotionFX { AZStd::string result; - EXPECT_TRUE(CommandSystem::GetCommandManager()->ExecuteCommand( - "Select -actorId " + AZStd::to_string(actor->GetID()), + EXPECT_TRUE(CommandSystem::GetCommandManager()->ExecuteCommand("Select -actorId " + AZStd::to_string(actor->GetID()), result)) << result.c_str(); } diff --git a/Gems/EMotionFX/Code/Tests/ProvidesUI/Ragdoll/CanCopyPasteJointLimits.cpp b/Gems/EMotionFX/Code/Tests/ProvidesUI/Ragdoll/CanCopyPasteJointLimits.cpp index 8e4fba0dd6..3f475c7916 100644 --- a/Gems/EMotionFX/Code/Tests/ProvidesUI/Ragdoll/CanCopyPasteJointLimits.cpp +++ b/Gems/EMotionFX/Code/Tests/ProvidesUI/Ragdoll/CanCopyPasteJointLimits.cpp @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -25,6 +24,7 @@ #include #include #include +#include #include namespace EMotionFX @@ -76,7 +76,9 @@ namespace EMotionFX return AZStd::make_unique(); }); - AutoRegisteredActor actor {ActorFactory::CreateAndInit(4)}; + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 4); + const Actor* actor = actorAsset->GetActor(); { AZStd::string result; diff --git a/Gems/EMotionFX/Code/Tests/RagdollCommandTests.cpp b/Gems/EMotionFX/Code/Tests/RagdollCommandTests.cpp index e9a4cc0c26..1004b0a1f6 100644 --- a/Gems/EMotionFX/Code/Tests/RagdollCommandTests.cpp +++ b/Gems/EMotionFX/Code/Tests/RagdollCommandTests.cpp @@ -99,28 +99,28 @@ namespace EMotionFX "l_hand", }; - CommandRagdollHelpers::AddJointsToRagdoll(m_actor->GetID(), {"l_shldr"}, &commandGroup); + CommandRagdollHelpers::AddJointsToRagdoll(GetActor()->GetID(), {"l_shldr"}, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)) << result.c_str(); EXPECT_THAT( - GetRagdollJointNames(m_actor.get()), + GetRagdollJointNames(GetActor()), testing::UnorderedPointwise( StrEq(), jointsToLeftShoulder ) ); - const AZStd::string serializedBeforeHandAdded = SerializePhysicsSetup(m_actor.get()); + const AZStd::string serializedBeforeHandAdded = SerializePhysicsSetup(GetActor()); // Adding l_hand should add l_upArm and l_loArm as well commandGroup.RemoveAllCommands(); - CommandRagdollHelpers::AddJointsToRagdoll(m_actor->GetID(), {"l_hand"}, &commandGroup); + CommandRagdollHelpers::AddJointsToRagdoll(GetActor()->GetID(), {"l_hand"}, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)) << result.c_str(); - const AZStd::string serializedAfterHandAdded = SerializePhysicsSetup(m_actor.get()); + const AZStd::string serializedAfterHandAdded = SerializePhysicsSetup(GetActor()); EXPECT_THAT( - GetRagdollJointNames(m_actor.get()), + GetRagdollJointNames(GetActor()), testing::UnorderedPointwise( StrEq(), jointsToLeftHand @@ -129,23 +129,23 @@ namespace EMotionFX EXPECT_TRUE(commandManager.Undo(result)) << result.c_str(); EXPECT_THAT( - GetRagdollJointNames(m_actor.get()), + GetRagdollJointNames(GetActor()), testing::UnorderedPointwise( StrEq(), jointsToLeftShoulder ) ); - EXPECT_THAT(SerializePhysicsSetup(m_actor.get()), StrEq(serializedBeforeHandAdded)); + EXPECT_THAT(SerializePhysicsSetup(GetActor()), StrEq(serializedBeforeHandAdded)); EXPECT_TRUE(commandManager.Redo(result)) << result.c_str(); EXPECT_THAT( - GetRagdollJointNames(m_actor.get()), + GetRagdollJointNames(GetActor()), testing::UnorderedPointwise( StrEq(), jointsToLeftHand ) ); - EXPECT_THAT(SerializePhysicsSetup(m_actor.get()), StrEq(serializedAfterHandAdded)); + EXPECT_THAT(SerializePhysicsSetup(GetActor()), StrEq(serializedAfterHandAdded)); } TEST_F(RagdollCommandTests, AddJointHigherInHierarchy) @@ -166,10 +166,10 @@ namespace EMotionFX "l_hand", }; - CommandRagdollHelpers::AddJointsToRagdoll(m_actor->GetID(), {"l_hand"}, &commandGroup); + CommandRagdollHelpers::AddJointsToRagdoll(GetActor()->GetID(), {"l_hand"}, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)) << result.c_str(); EXPECT_THAT( - GetRagdollJointNames(m_actor.get()), + GetRagdollJointNames(GetActor()), testing::UnorderedPointwise( StrEq(), jointsToLeftHand @@ -178,10 +178,10 @@ namespace EMotionFX // l_shldr should already be in the ragdoll, so adding it should do nothing commandGroup.RemoveAllCommands(); - CommandRagdollHelpers::AddJointsToRagdoll(m_actor->GetID(), {"l_shldr"}, &commandGroup); + CommandRagdollHelpers::AddJointsToRagdoll(GetActor()->GetID(), {"l_shldr"}, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)) << result.c_str(); EXPECT_THAT( - GetRagdollJointNames(m_actor.get()), + GetRagdollJointNames(GetActor()), testing::UnorderedPointwise( StrEq(), jointsToLeftHand @@ -190,11 +190,11 @@ namespace EMotionFX // Undo here undoes the addition of l_hand EXPECT_TRUE(commandManager.Undo(result)) << result.c_str(); - EXPECT_TRUE(GetRagdollJointNames(m_actor.get()).empty()); + EXPECT_TRUE(GetRagdollJointNames(GetActor()).empty()); EXPECT_TRUE(commandManager.Redo(result)) << result.c_str(); EXPECT_THAT( - GetRagdollJointNames(m_actor.get()), + GetRagdollJointNames(GetActor()), testing::UnorderedPointwise( StrEq(), jointsToLeftHand @@ -221,16 +221,16 @@ namespace EMotionFX }; // Add a joint to the ragdoll that does not make a chain all the way to the root - EXPECT_TRUE(commandManager.ExecuteCommand(aznew CommandAddRagdollJoint(m_actor->GetID(), "l_shldr"), result)) << result.c_str(); + EXPECT_TRUE(commandManager.ExecuteCommand(aznew CommandAddRagdollJoint(GetActor()->GetID(), "l_shldr"), result)) << result.c_str(); EXPECT_THAT( - GetRagdollJointNames(m_actor.get()), + GetRagdollJointNames(GetActor()), testing::UnorderedPointwise(StrEq(), AZStd::vector{"l_shldr"}) ); - CommandRagdollHelpers::AddJointsToRagdoll(m_actor->GetID(), {"l_hand"}, &commandGroup); + CommandRagdollHelpers::AddJointsToRagdoll(GetActor()->GetID(), {"l_hand"}, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)) << result.c_str(); EXPECT_THAT( - GetRagdollJointNames(m_actor.get()), + GetRagdollJointNames(GetActor()), testing::UnorderedPointwise(StrEq(), jointsToLeftHand) ); } @@ -250,17 +250,17 @@ namespace EMotionFX }; // Add joints from the root to the left hand - CommandRagdollHelpers::AddJointsToRagdoll(m_actor->GetID(), {"l_hand"}, &commandGroup); + CommandRagdollHelpers::AddJointsToRagdoll(GetActor()->GetID(), {"l_hand"}, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)) << result.c_str(); // Removing the left shoulder should remove the elbow, wrist, and hand // as well commandGroup.RemoveAllCommands(); - CommandRagdollHelpers::RemoveJointsFromRagdoll(m_actor->GetID(), {"l_shldr"}, &commandGroup); + CommandRagdollHelpers::RemoveJointsFromRagdoll(GetActor()->GetID(), {"l_shldr"}, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)) << result.c_str(); EXPECT_THAT( - GetRagdollJointNames(m_actor.get()), + GetRagdollJointNames(GetActor()), testing::UnorderedPointwise(StrEq(), jointsToSpine3) ); } @@ -271,24 +271,24 @@ namespace EMotionFX CommandSystem::CommandManager commandManager; MCore::CommandGroup commandGroup; - CommandRagdollHelpers::AddJointsToRagdoll(m_actor->GetID(), {"l_hand"}, &commandGroup); + CommandRagdollHelpers::AddJointsToRagdoll(GetActor()->GetID(), {"l_hand"}, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)) << result.c_str(); - const AZStd::string serializedBeforeSphereAdded = SerializePhysicsSetup(m_actor.get()); + const AZStd::string serializedBeforeSphereAdded = SerializePhysicsSetup(GetActor()); - CommandColliderHelpers::AddCollider(m_actor->GetID(), "l_hand", + CommandColliderHelpers::AddCollider(GetActor()->GetID(), "l_hand", PhysicsSetup::Ragdoll, azrtti_typeid()); - const AZStd::string serializedAfterSphereAdded = SerializePhysicsSetup(m_actor.get()); + const AZStd::string serializedAfterSphereAdded = SerializePhysicsSetup(GetActor()); EXPECT_THAT(serializedAfterSphereAdded, ::testing::Not(StrEq(serializedBeforeSphereAdded))); EXPECT_TRUE(commandManager.Undo(result)) << result.c_str(); - EXPECT_THAT(SerializePhysicsSetup(m_actor.get()), StrEq(serializedBeforeSphereAdded)); + EXPECT_THAT(SerializePhysicsSetup(GetActor()), StrEq(serializedBeforeSphereAdded)); EXPECT_TRUE(commandManager.Redo(result)) << result.c_str(); - EXPECT_THAT(SerializePhysicsSetup(m_actor.get()), StrEq(serializedAfterSphereAdded)); + EXPECT_THAT(SerializePhysicsSetup(GetActor()), StrEq(serializedAfterSphereAdded)); } } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/Tests/SimulatedObjectCommandTests.cpp b/Gems/EMotionFX/Code/Tests/SimulatedObjectCommandTests.cpp index 4bac70c13d..dab761f649 100644 --- a/Gems/EMotionFX/Code/Tests/SimulatedObjectCommandTests.cpp +++ b/Gems/EMotionFX/Code/Tests/SimulatedObjectCommandTests.cpp @@ -55,25 +55,25 @@ namespace EMotionFX CommandSystem::CommandManager commandManager; MCore::CommandGroup commandGroup; - const uint32 actorId = m_actor->GetID(); + const uint32 actorId = GetActor()->GetID(); const AZStd::vector jointNames = GetTestJointNames(); // 1. Add simulated object. - const AZStd::string serializedBeforeAdd = SerializeSimulatedObjectSetup(m_actor.get()); + const AZStd::string serializedBeforeAdd = SerializeSimulatedObjectSetup(GetActor()); CommandSimulatedObjectHelpers::AddSimulatedObject(actorId, AZStd::nullopt, &commandGroup); CommandSimulatedObjectHelpers::AddSimulatedObject(actorId, AZStd::nullopt, &commandGroup); CommandSimulatedObjectHelpers::AddSimulatedObject(actorId, AZStd::nullopt, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)); - const AZStd::string serializedAfterAdd = SerializeSimulatedObjectSetup(m_actor.get()); - EXPECT_EQ(3, CountSimulatedObjects(m_actor.get())); + const AZStd::string serializedAfterAdd = SerializeSimulatedObjectSetup(GetActor()); + EXPECT_EQ(3, CountSimulatedObjects(GetActor())); EXPECT_TRUE(commandManager.Undo(result)); - EXPECT_EQ(0, CountSimulatedObjects(m_actor.get())); - EXPECT_EQ(serializedBeforeAdd, SerializeSimulatedObjectSetup(m_actor.get())); + EXPECT_EQ(0, CountSimulatedObjects(GetActor())); + EXPECT_EQ(serializedBeforeAdd, SerializeSimulatedObjectSetup(GetActor())); EXPECT_TRUE(commandManager.Redo(result)); - EXPECT_EQ(3, CountSimulatedObjects(m_actor.get())); - EXPECT_EQ(serializedAfterAdd, SerializeSimulatedObjectSetup(m_actor.get())); + EXPECT_EQ(3, CountSimulatedObjects(GetActor())); + EXPECT_EQ(serializedAfterAdd, SerializeSimulatedObjectSetup(GetActor())); // 2. Remove simulated object. commandGroup.RemoveAllCommands(); @@ -81,22 +81,22 @@ namespace EMotionFX CommandSimulatedObjectHelpers::RemoveSimulatedObject(actorId, 0, &commandGroup); CommandSimulatedObjectHelpers::RemoveSimulatedObject(actorId, 0, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)); - EXPECT_EQ(0, CountSimulatedObjects(m_actor.get())); - EXPECT_EQ(serializedBeforeAdd, SerializeSimulatedObjectSetup(m_actor.get())); + EXPECT_EQ(0, CountSimulatedObjects(GetActor())); + EXPECT_EQ(serializedBeforeAdd, SerializeSimulatedObjectSetup(GetActor())); EXPECT_TRUE(commandManager.Undo(result)); - EXPECT_EQ(3, CountSimulatedObjects(m_actor.get())); - EXPECT_EQ(serializedAfterAdd, SerializeSimulatedObjectSetup(m_actor.get())); + EXPECT_EQ(3, CountSimulatedObjects(GetActor())); + EXPECT_EQ(serializedAfterAdd, SerializeSimulatedObjectSetup(GetActor())); EXPECT_TRUE(commandManager.Redo(result)); - EXPECT_EQ(0, CountSimulatedObjects(m_actor.get())); - EXPECT_EQ(serializedBeforeAdd, SerializeSimulatedObjectSetup(m_actor.get())); + EXPECT_EQ(0, CountSimulatedObjects(GetActor())); + EXPECT_EQ(serializedBeforeAdd, SerializeSimulatedObjectSetup(GetActor())); // 3. Add simulated joints. // 3.1 Add a simulated object first to put in the simulated joints. commandGroup.RemoveAllCommands(); CommandSimulatedObjectHelpers::AddSimulatedObject(actorId); - const AZStd::string serialized3_1 = SerializeSimulatedObjectSetup(m_actor.get()); + const AZStd::string serialized3_1 = SerializeSimulatedObjectSetup(GetActor()); // 3.2 Add simulated joints. // Joint hierarchy as follow: @@ -105,7 +105,7 @@ namespace EMotionFX // --l_loLeg // --l_ankle // --l_ball - const Skeleton* skeleton = m_actor->GetSkeleton(); + const Skeleton* skeleton = GetActor()->GetSkeleton(); const size_t l_upLegIdx = skeleton->FindNodeByName("l_upLeg")->GetNodeIndex(); const size_t l_upLegRollIdx = skeleton->FindNodeByName("l_upLegRoll")->GetNodeIndex(); const size_t l_loLegIdx = skeleton->FindNodeByName("l_loLeg")->GetNodeIndex(); @@ -113,33 +113,33 @@ namespace EMotionFX const size_t l_ballIdx = skeleton->FindNodeByName("l_ball")->GetNodeIndex(); CommandSimulatedObjectHelpers::AddSimulatedJoints(actorId, {l_upLegIdx, l_upLegRollIdx, l_loLegIdx, l_ankleIdx, l_ballIdx}, 0, false, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)); - const AZStd::string serialized3_2 = SerializeSimulatedObjectSetup(m_actor.get()); - EXPECT_EQ(5, CountSimulatedJoints(m_actor.get(), 0)); - EXPECT_EQ(2, CountChildJoints(m_actor.get(), 0, l_upLegIdx)); - EXPECT_EQ(0, CountChildJoints(m_actor.get(), 0, l_upLegRollIdx)); - EXPECT_EQ(1, CountChildJoints(m_actor.get(), 0, l_loLegIdx)); + const AZStd::string serialized3_2 = SerializeSimulatedObjectSetup(GetActor()); + EXPECT_EQ(5, CountSimulatedJoints(GetActor(), 0)); + EXPECT_EQ(2, CountChildJoints(GetActor(), 0, l_upLegIdx)); + EXPECT_EQ(0, CountChildJoints(GetActor(), 0, l_upLegRollIdx)); + EXPECT_EQ(1, CountChildJoints(GetActor(), 0, l_loLegIdx)); EXPECT_TRUE(commandManager.Undo(result)); - EXPECT_EQ(0, CountSimulatedJoints(m_actor.get(), 0)); - EXPECT_EQ(serialized3_1, SerializeSimulatedObjectSetup(m_actor.get())); + EXPECT_EQ(0, CountSimulatedJoints(GetActor(), 0)); + EXPECT_EQ(serialized3_1, SerializeSimulatedObjectSetup(GetActor())); EXPECT_TRUE(commandManager.Redo(result)); - EXPECT_EQ(5, CountSimulatedJoints(m_actor.get(), 0)); - EXPECT_EQ(serialized3_2, SerializeSimulatedObjectSetup(m_actor.get())); + EXPECT_EQ(5, CountSimulatedJoints(GetActor(), 0)); + EXPECT_EQ(serialized3_2, SerializeSimulatedObjectSetup(GetActor())); // 4 Remove simulated joints. // 4.1 Test sparse chain. - EXPECT_EQ(1, CountRootJoints(m_actor.get(), 0)); + EXPECT_EQ(1, CountRootJoints(GetActor(), 0)); commandGroup.RemoveAllCommands(); CommandSimulatedObjectHelpers::RemoveSimulatedJoints(actorId, {l_loLegIdx}, 0, false, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)); - EXPECT_EQ(2, CountRootJoints(m_actor.get(), 0)); + EXPECT_EQ(2, CountRootJoints(GetActor(), 0)); EXPECT_TRUE(commandManager.Undo(result)); - EXPECT_EQ(1, CountRootJoints(m_actor.get(), 0)); + EXPECT_EQ(1, CountRootJoints(GetActor(), 0)); EXPECT_TRUE(commandManager.Redo(result)); - EXPECT_EQ(2, CountRootJoints(m_actor.get(), 0)); + EXPECT_EQ(2, CountRootJoints(GetActor(), 0)); EXPECT_TRUE(commandManager.Undo(result)); @@ -147,23 +147,23 @@ namespace EMotionFX commandGroup.RemoveAllCommands(); CommandSimulatedObjectHelpers::RemoveSimulatedJoints(actorId, { l_upLegIdx, l_upLegRollIdx, l_loLegIdx, l_ankleIdx, l_ballIdx }, 0, false, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)); - EXPECT_EQ(0, CountSimulatedJoints(m_actor.get(), 0)); - EXPECT_EQ(serialized3_1, SerializeSimulatedObjectSetup(m_actor.get())); + EXPECT_EQ(0, CountSimulatedJoints(GetActor(), 0)); + EXPECT_EQ(serialized3_1, SerializeSimulatedObjectSetup(GetActor())); EXPECT_TRUE(commandManager.Undo(result)); - EXPECT_EQ(5, CountSimulatedJoints(m_actor.get(), 0)); - EXPECT_EQ(serialized3_2, SerializeSimulatedObjectSetup(m_actor.get())); + EXPECT_EQ(5, CountSimulatedJoints(GetActor(), 0)); + EXPECT_EQ(serialized3_2, SerializeSimulatedObjectSetup(GetActor())); // 4.3 Test removing the root joint and children. commandGroup.RemoveAllCommands(); CommandSimulatedObjectHelpers::RemoveSimulatedJoints(actorId, { l_upLegIdx }, 0, true, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)); - EXPECT_EQ(0, CountSimulatedJoints(m_actor.get(), 0)); - EXPECT_EQ(serialized3_1, SerializeSimulatedObjectSetup(m_actor.get())); + EXPECT_EQ(0, CountSimulatedJoints(GetActor(), 0)); + EXPECT_EQ(serialized3_1, SerializeSimulatedObjectSetup(GetActor())); EXPECT_TRUE(commandManager.Undo(result)); - EXPECT_EQ(5, CountSimulatedJoints(m_actor.get(), 0)); - EXPECT_EQ(serialized3_2, SerializeSimulatedObjectSetup(m_actor.get())); + EXPECT_EQ(5, CountSimulatedJoints(GetActor(), 0)); + EXPECT_EQ(serialized3_2, SerializeSimulatedObjectSetup(GetActor())); } TEST_F(SimulatedObjectCommandTests, SimulatedObjectCommands_UndoRemoveJointTest) @@ -172,35 +172,35 @@ namespace EMotionFX CommandSystem::CommandManager commandManager; MCore::CommandGroup commandGroup; - const uint32 actorId = m_actor->GetID(); + const uint32 actorId = GetActor()->GetID(); const AZStd::vector jointNames = GetTestJointNames(); // 1. Add simulated object CommandSimulatedObjectHelpers::AddSimulatedObject(actorId, AZStd::nullopt, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)); - const AZStd::string serializedBase = SerializeSimulatedObjectSetup(m_actor.get()); + const AZStd::string serializedBase = SerializeSimulatedObjectSetup(GetActor()); const size_t simulatedObjectIndex = 0; // 2. Add r_upLeg simulated joints - const Skeleton* skeleton = m_actor->GetSkeleton(); + const Skeleton* skeleton = GetActor()->GetSkeleton(); const size_t r_upLegIdx = skeleton->FindNodeByName("r_upLeg")->GetNodeIndex(); const size_t r_loLegIdx = skeleton->FindNodeByName("r_loLeg")->GetNodeIndex(); CommandSimulatedObjectHelpers::AddSimulatedJoints(actorId, { r_upLegIdx, r_loLegIdx }, 0, false); - EXPECT_EQ(2, CountSimulatedJoints(m_actor.get(), 0)); - const AZStd::string serializedUpLeg = SerializeSimulatedObjectSetup(m_actor.get()); + EXPECT_EQ(2, CountSimulatedJoints(GetActor(), 0)); + const AZStd::string serializedUpLeg = SerializeSimulatedObjectSetup(GetActor()); // 3. Remove the r_loLeg simulated joint AZStd::vector jointsToBeRemoved; commandGroup.RemoveAllCommands(); CommandSimulatedObjectHelpers::RemoveSimulatedJoints(actorId, { r_upLegIdx }, simulatedObjectIndex, true, &commandGroup); EXPECT_TRUE(commandManager.ExecuteCommandGroup(commandGroup, result)); - EXPECT_EQ(0, CountSimulatedJoints(m_actor.get(), 0)); - EXPECT_EQ(serializedBase, SerializeSimulatedObjectSetup(m_actor.get())); + EXPECT_EQ(0, CountSimulatedJoints(GetActor(), 0)); + EXPECT_EQ(serializedBase, SerializeSimulatedObjectSetup(GetActor())); // 4. Undo // This recreates r_loLeg and r_loLeg but won't add all other children recursively as only these two joints got aded in step 3. EXPECT_TRUE(commandManager.Undo(result)); - EXPECT_EQ(2, CountSimulatedJoints(m_actor.get(), 0)); - EXPECT_EQ(serializedUpLeg, SerializeSimulatedObjectSetup(m_actor.get())); + EXPECT_EQ(2, CountSimulatedJoints(GetActor(), 0)); + EXPECT_EQ(serializedUpLeg, SerializeSimulatedObjectSetup(GetActor())); } } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/Tests/SimulatedObjectModelTests.cpp b/Gems/EMotionFX/Code/Tests/SimulatedObjectModelTests.cpp index 41269cec77..85da96412b 100644 --- a/Gems/EMotionFX/Code/Tests/SimulatedObjectModelTests.cpp +++ b/Gems/EMotionFX/Code/Tests/SimulatedObjectModelTests.cpp @@ -22,17 +22,21 @@ #include #include #include +#include namespace EMotionFX { using SimulatedObjectModelTestsFixture = UIFixture; TEST_F(SimulatedObjectModelTestsFixture, CanUndoAddSimulatedObjectAndSimulatedJointWithChildren) { - AutoRegisteredActor actor = ActorFactory::CreateAndInit(3, "simulatedObjectModelTestActor"); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = + TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 3, "simulatedObjectModelTestActor"); + const Actor* actor = actorAsset->GetActor(); EMotionFX::SimulatedObjectWidget* simulatedObjectWidget = static_cast(EMStudio::GetPluginManager()->FindActivePlugin(EMotionFX::SimulatedObjectWidget::CLASS_ID)); ASSERT_TRUE(simulatedObjectWidget) << "Simulated Object plugin not loaded"; - simulatedObjectWidget->ActorSelectionChanged(actor.get()); + simulatedObjectWidget->ActorSelectionChanged(actorAsset->GetActor()); SimulatedObjectModel* model = simulatedObjectWidget->GetSimulatedObjectModel(); diff --git a/Gems/EMotionFX/Code/Tests/SimulatedObjectSerializeTests.cpp b/Gems/EMotionFX/Code/Tests/SimulatedObjectSerializeTests.cpp index c261f63bc1..e5c2c5ce4f 100644 --- a/Gems/EMotionFX/Code/Tests/SimulatedObjectSerializeTests.cpp +++ b/Gems/EMotionFX/Code/Tests/SimulatedObjectSerializeTests.cpp @@ -20,7 +20,7 @@ namespace EMotionFX TEST_F(SimulatedObjectSerializeTests, SerializeTest) { - SimulatedObjectSetup* setup = m_actor->GetSimulatedObjectSetup().get(); + SimulatedObjectSetup* setup = GetActor()->GetSimulatedObjectSetup().get(); // Build some setup. SimulatedObject* object = setup->AddSimulatedObject(); @@ -29,7 +29,7 @@ namespace EMotionFX object->SetGravityFactor(3.0f); object->SetStiffnessFactor(4.0f); const AZStd::vector jointNames = { "l_upArm", "l_loArm", "l_hand" }; - Skeleton* skeleton = m_actor->GetSkeleton(); + Skeleton* skeleton = GetActor()->GetSkeleton(); for (const AZStd::string& name : jointNames) { size_t skeletonJointIndex; @@ -50,7 +50,7 @@ namespace EMotionFX object->GetSimulatedJoint(0)->SetPinned(true); // Serialize it and deserialize it. - const AZStd::string serialized = SerializeSimulatedObjectSetup(m_actor.get()); + const AZStd::string serialized = SerializeSimulatedObjectSetup(GetActor()); AZStd::unique_ptr loadedSetup(DeserializeSimulatedObjectSetup(serialized)); // Verify some of the contents of the deserialized version. diff --git a/Gems/EMotionFX/Code/Tests/SkeletalLODTests.cpp b/Gems/EMotionFX/Code/Tests/SkeletalLODTests.cpp index 1252eb36ae..54a81cb559 100644 --- a/Gems/EMotionFX/Code/Tests/SkeletalLODTests.cpp +++ b/Gems/EMotionFX/Code/Tests/SkeletalLODTests.cpp @@ -22,13 +22,13 @@ namespace EMotionFX void SetUp() { ActorFixture::SetUp(); - m_actor->AddLODLevel(); + GetActor()->AddLODLevel(); DisableJointsForLOD(m_disabledJointNames, 1); } void DisableJointsForLOD(const std::vector& jointNames, size_t lodLevel) { - const Skeleton* skeleton = m_actor->GetSkeleton(); + const Skeleton* skeleton = GetActor()->GetSkeleton(); for (const std::string& jointName : jointNames) { Node* joint = skeleton->FindNodeByName(jointName.c_str()); diff --git a/Gems/EMotionFX/Code/Tests/TestAssetCode/TestActorAssets.cpp b/Gems/EMotionFX/Code/Tests/TestAssetCode/TestActorAssets.cpp index 6375d48c6b..bb3c4f76e2 100644 --- a/Gems/EMotionFX/Code/Tests/TestAssetCode/TestActorAssets.cpp +++ b/Gems/EMotionFX/Code/Tests/TestAssetCode/TestActorAssets.cpp @@ -10,9 +10,10 @@ #include #include #include -#include #include #include +#include +#include namespace EMotionFX { diff --git a/Gems/EMotionFX/Code/Tests/TestAssetCode/TestActorAssets.h b/Gems/EMotionFX/Code/Tests/TestAssetCode/TestActorAssets.h index 3a041fcf34..5b75ddf590 100644 --- a/Gems/EMotionFX/Code/Tests/TestAssetCode/TestActorAssets.h +++ b/Gems/EMotionFX/Code/Tests/TestAssetCode/TestActorAssets.h @@ -10,6 +10,9 @@ #include #include +#include +#include +#include namespace EMotionFX { @@ -18,5 +21,14 @@ namespace EMotionFX public: static AZStd::string FileToBase64(const char* filePath); static AZ::Data::Asset GetAssetFromActor(const AZ::Data::AssetId& assetId, AZStd::unique_ptr&& actor); + + template + static AZ::Data::Asset CreateActorAssetAndRegister(const AZ::Data::AssetId& assetId, Args&&... args) + { + AZStd::unique_ptr actor = ActorFactory::CreateAndInit(AZStd::forward(args)...); + AZ::Data::Asset actorAsset = TestActorAssets::GetAssetFromActor(assetId, AZStd::move(actor)); + GetEMotionFX().GetActorManager()->RegisterActor(actorAsset); + return AZStd::move(actorAsset); + } }; } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/Tests/UI/CanAddJointAndChildren.cpp b/Gems/EMotionFX/Code/Tests/UI/CanAddJointAndChildren.cpp index 59506a9d43..32240ba409 100644 --- a/Gems/EMotionFX/Code/Tests/UI/CanAddJointAndChildren.cpp +++ b/Gems/EMotionFX/Code/Tests/UI/CanAddJointAndChildren.cpp @@ -16,13 +16,13 @@ #include #include -#include #include #include #include #include #include +#include namespace EMotionFX { @@ -37,8 +37,11 @@ namespace EMotionFX RecordProperty("test_case_id", "C13048819"); // Create an actor - AutoRegisteredActor actor = ActorFactory::CreateAndInit(5, "SimpleActor"); - ActorInstance* actorInstance = ActorInstance::Create(actor.get()); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = + TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 5, "SimpleActor"); + ActorInstance* actorInstance = ActorInstance::Create(actorAsset->GetActor()); + const Actor* actor = actorAsset->GetActor(); // Open simulated objects layout EMStudio::GetMainWindow()->ApplicationModeChanged("SimulatedObjects"); diff --git a/Gems/EMotionFX/Code/Tests/UI/CanAddSimulatedObject.cpp b/Gems/EMotionFX/Code/Tests/UI/CanAddSimulatedObject.cpp index e1c4525a9e..0820895db8 100644 --- a/Gems/EMotionFX/Code/Tests/UI/CanAddSimulatedObject.cpp +++ b/Gems/EMotionFX/Code/Tests/UI/CanAddSimulatedObject.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -27,6 +26,7 @@ #include #include +#include #include #include @@ -81,9 +81,9 @@ namespace EMotionFX inputDialog->accept(); // There is one and only one simulated objects - ASSERT_EQ(m_actor->GetSimulatedObjectSetup()->GetNumSimulatedObjects(), 1); + ASSERT_EQ(m_actorAsset->GetActor()->GetSimulatedObjectSetup()->GetNumSimulatedObjects(), 1); // Check it has the correct name - EXPECT_STREQ(m_actor->GetSimulatedObjectSetup()->GetSimulatedObject(0)->GetName().c_str(), objectName); + EXPECT_STREQ(m_actorAsset->GetActor()->GetSimulatedObjectSetup()->GetSimulatedObject(0)->GetName().c_str(), objectName); } @@ -112,14 +112,16 @@ namespace EMotionFX }); ASSERT_NE(addCapsuleColliderAction, addSelectedColliderMenuActions.end()); - size_t numCapsuleColliders = PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule); + size_t numCapsuleColliders = PhysicsSetupUtils::CountColliders( + m_actorAsset->GetActor(), PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule); (*addCapsuleColliderAction)->trigger(); // Delete the context menu, otherwise there it will still be around during this frame as the Qt event loop has not been run. delete contextMenu; - const size_t numCapsuleCollidersAfterAdd = PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule); + const size_t numCapsuleCollidersAfterAdd = PhysicsSetupUtils::CountColliders( + m_actorAsset->GetActor(), PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule); ASSERT_EQ(numCapsuleCollidersAfterAdd, numCapsuleColliders + 1); @@ -127,7 +129,7 @@ namespace EMotionFX } protected: - AutoRegisteredActor m_actor; + AZ::Data::Asset m_actorAsset; EMotionFX::SimulatedObjectWidget* m_simulatedObjectWidget = nullptr; EMotionFX::SkeletonOutlinerPlugin* m_skeletonOutliner = nullptr; @@ -144,7 +146,8 @@ namespace EMotionFX { RecordProperty("test_case_id", "C13048820"); - m_actor = ActorFactory::CreateAndInit(1, "CanAddSimulatedObjectActor"); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + m_actorAsset = TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 1, "CanAddSimulatedObjectActor"); CreateSimulateObject("New simulated object"); } @@ -153,9 +156,11 @@ namespace EMotionFX { RecordProperty("test_case_id", "C13048818"); - AutoRegisteredActor actor = ActorFactory::CreateAndInit(2, "CanAddSimulatedObjectWithJointsActor"); - - ActorInstance* actorInstance = ActorInstance::Create(actor.get()); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = + TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 2, "CanAddSimulatedObjectWithJointsActor"); + Actor* actor = actorAsset->GetActor(); + ActorInstance* actorInstance = ActorInstance::Create(actor); EMStudio::GetMainWindow()->ApplicationModeChanged("SimulatedObjects"); @@ -216,7 +221,9 @@ namespace EMotionFX { RecordProperty("test_case_id", "C13048820a"); - m_actor = ActorFactory::CreateAndInit(5, "CanAddSimulatedObjectActor"); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + m_actorAsset = TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 5, "CanAddSimulatedObjectActor"); + Actor* actor = m_actorAsset->GetActor(); CreateSimulateObject("sim1"); @@ -261,8 +268,8 @@ namespace EMotionFX inputDialog->SetText("sim2"); inputDialog->accept(); - ASSERT_EQ(m_actor->GetSimulatedObjectSetup()->GetNumSimulatedObjects(), 2); - const auto simulatedObject = m_actor->GetSimulatedObjectSetup()->GetSimulatedObject(1); + ASSERT_EQ(actor->GetSimulatedObjectSetup()->GetNumSimulatedObjects(), 2); + const auto simulatedObject = actor->GetSimulatedObjectSetup()->GetSimulatedObject(1); EXPECT_STREQ(simulatedObject->GetName().c_str(), "sim2"); } @@ -270,7 +277,9 @@ namespace EMotionFX { RecordProperty("test_case_id", "C13048816"); - m_actor = ActorFactory::CreateAndInit(5, "CanAddSimulatedObjectActor"); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + m_actorAsset = TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 5, "CanAddSimulatedObjectActor"); + Actor* actor = m_actorAsset->GetActor(); CreateSimulateObject("sim1"); @@ -301,25 +310,25 @@ namespace EMotionFX QAction* addCapsuleColliderAction; ASSERT_TRUE(UIFixture::GetActionFromContextMenu(addCapsuleColliderAction, addSelectedColliderMenu, "Capsule")); - size_t numCapsuleColliders = PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule); + size_t numCapsuleColliders = PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule); EXPECT_EQ(numCapsuleColliders, 0); addCapsuleColliderAction->trigger(); // Check that a collider has been added. - size_t numCollidersAfterAddCapsule = PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule); + size_t numCollidersAfterAddCapsule = PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule); ASSERT_EQ(numCollidersAfterAddCapsule, numCapsuleColliders + 1) << "Capsule collider not added."; QAction* addSphereColliderAction; ASSERT_TRUE(UIFixture::GetActionFromContextMenu(addSphereColliderAction, addSelectedColliderMenu, "Sphere")); - const size_t numSphereColliders = PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Sphere); + const size_t numSphereColliders = PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Sphere); EXPECT_EQ(numSphereColliders, 0); addSphereColliderAction->trigger(); // Check that a second collider has been added. - const size_t numCollidersAfterAddSphere = PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Sphere); + const size_t numCollidersAfterAddSphere = PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Sphere); ASSERT_EQ(numCollidersAfterAddSphere, numSphereColliders + 1) << "Sphere collider not added."; } @@ -327,7 +336,9 @@ namespace EMotionFX { RecordProperty("test_case_id", "C13048821"); - m_actor = ActorFactory::CreateAndInit(1, "CanRemoveSimulatedObjectActor"); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + m_actorAsset = TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 1, "CanRemoveSimulatedObjectActor"); + Actor* actor = m_actorAsset->GetActor(); CreateSimulateObject("TestObject1"); @@ -350,14 +361,16 @@ namespace EMotionFX ASSERT_TRUE(UIFixture::GetActionFromContextMenu(removeObjectAction, contextMenu, "Remove object")); removeObjectAction->trigger(); - ASSERT_EQ(m_actor->GetSimulatedObjectSetup()->GetNumSimulatedObjects(), 0); + ASSERT_EQ(actor->GetSimulatedObjectSetup()->GetNumSimulatedObjects(), 0); } TEST_F(CanAddSimulatedObjectFixture, CanAddColliderToSimulatedObjectFromInspector) { RecordProperty("test_case_id", "C20385259"); - - m_actor = ActorFactory::CreateAndInit(5, "CanAddSimulatedObjectActor"); + + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + m_actorAsset = TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 5, "CanAddSimulatedObjectActor"); + Actor* actor = m_actorAsset->GetActor(); CreateSimulateObject("sim1"); @@ -380,10 +393,12 @@ namespace EMotionFX // Send the left button click directly to the button QTest::mouseClick(addColliderButton, Qt::LeftButton); - const size_t numCapsuleColliders = PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule); + const size_t numCapsuleColliders = + PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule); EXPECT_EQ(numCapsuleColliders, 0); - const size_t numSphereColliders = PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Sphere); + const size_t numSphereColliders = + PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Sphere); EXPECT_EQ(numSphereColliders, 0); QMenu* contextMenu = addColliderButton->findChild("EMFX.AddColliderButton.ContextMenu"); @@ -392,13 +407,15 @@ namespace EMotionFX QAction* addCapsuleAction; ASSERT_TRUE(UIFixture::GetActionFromContextMenu(addCapsuleAction, contextMenu, "Add capsule")); addCapsuleAction->trigger(); - const size_t numCollidersAfterAddCapsule = PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule); + const size_t numCollidersAfterAddCapsule = + PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule); ASSERT_EQ(numCollidersAfterAddCapsule, numCapsuleColliders + 1) << "Capsule collider not added."; QAction* addSphereAction; ASSERT_TRUE(UIFixture::GetActionFromContextMenu(addSphereAction, contextMenu, "Add sphere")); addSphereAction->trigger(); - const size_t numCollidersAfterAddSphere = PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Sphere); + const size_t numCollidersAfterAddSphere = + PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Sphere); ASSERT_EQ(numCollidersAfterAddSphere, numSphereColliders + 1) << "Sphere collider not added."; } @@ -406,7 +423,9 @@ namespace EMotionFX { RecordProperty("test_case_id", "C13048818"); - m_actor = ActorFactory::CreateAndInit(7, "CanAddSimulatedObjectActor"); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + m_actorAsset = TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 7, "CanAddSimulatedObjectActor"); + Actor* actor = m_actorAsset->GetActor(); CreateSimulateObject("ANY"); @@ -442,7 +461,7 @@ namespace EMotionFX messageBoxPopupHandler.WaitForPopupPressDialogButton(QDialogButtonBox::No); newSimulatedObjectAction->trigger(); - const EMotionFX::SimulatedObject* simulatedObject = m_actor->GetSimulatedObjectSetup()->GetSimulatedObject(0); + const EMotionFX::SimulatedObject* simulatedObject = actor->GetSimulatedObjectSetup()->GetSimulatedObject(0); EXPECT_EQ(simulatedObject->GetNumSimulatedRootJoints(), 1); EXPECT_EQ(simulatedObject->GetNumSimulatedJoints(), 3); } @@ -450,7 +469,9 @@ namespace EMotionFX { RecordProperty("test_case_id", "C13048817"); - m_actor = ActorFactory::CreateAndInit(5, "CanAddSimulatedObjectActor"); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + m_actorAsset = TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 5, "CanAddSimulatedObjectActor"); + Actor* actor = m_actorAsset->GetActor(); EMStudio::GetMainWindow()->ApplicationModeChanged("SimulatedObjects"); @@ -470,7 +491,7 @@ namespace EMotionFX AddCapsuleColliderToJointIndex(3); AddCapsuleColliderToJointIndex(4); - const size_t numCollidersAfterAdd = PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::SimulatedObjectCollider); + const size_t numCollidersAfterAdd = PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider); EXPECT_EQ(numCollidersAfterAdd, 2); m_indexList.clear(); @@ -498,7 +519,7 @@ namespace EMotionFX removeAction->trigger(); // Check that one of the colliders is now gone. - const size_t numCollidersAfterFirstRemove = PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::SimulatedObjectCollider); + const size_t numCollidersAfterFirstRemove = PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider); ASSERT_EQ(numCollidersAfterFirstRemove, numCollidersAfterAdd - 1) << "RemoveCollider action in Simulated Object Inspector failed."; // Now do the same thing using the Simulated Object Inspector context menu. @@ -536,7 +557,7 @@ namespace EMotionFX delAction->trigger(); // Check that we have the number of colliders we started we expect. - const size_t numCollidersAfterSecondRemove = PhysicsSetupUtils::CountColliders(m_actor.get(), PhysicsSetup::SimulatedObjectCollider); + const size_t numCollidersAfterSecondRemove = PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider); ASSERT_EQ(numCollidersAfterSecondRemove, numCollidersAfterAdd - 2); } diff --git a/Gems/EMotionFX/Code/Tests/UI/CanAddToSimulatedObject.cpp b/Gems/EMotionFX/Code/Tests/UI/CanAddToSimulatedObject.cpp index e27d558664..a10ba352d2 100644 --- a/Gems/EMotionFX/Code/Tests/UI/CanAddToSimulatedObject.cpp +++ b/Gems/EMotionFX/Code/Tests/UI/CanAddToSimulatedObject.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -52,9 +53,11 @@ namespace EMotionFX { RecordProperty("test_case_id", "C14603914"); - AutoRegisteredActor actor = ActorFactory::CreateAndInit(7, "CanAddToSimulatedObjectActor"); - - ActorInstance* actorInstance = ActorInstance::Create(actor.get()); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = + TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 7, "CanAddToSimulatedObjectActor"); + Actor* actor = actorAsset->GetActor(); + ActorInstance* actorInstance = ActorInstance::Create(actor); // Change the Editor mode to Simulated Objects EMStudio::GetMainWindow()->ApplicationModeChanged("SimulatedObjects"); @@ -165,9 +168,11 @@ namespace EMotionFX }); RecordProperty("test_case_id", "C13291807"); - AutoRegisteredActor actor = ActorFactory::CreateAndInit(7, "CanAddToSimulatedObjectActor"); - - ActorInstance* actorInstance = ActorInstance::Create(actor.get()); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = + TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 7, "CanAddToSimulatedObjectActor"); + Actor* actor = actorAsset->GetActor(); + ActorInstance* actorInstance = ActorInstance::Create(actor); // Change the Editor mode to Physics EMStudio::GetMainWindow()->ApplicationModeChanged("Physics"); diff --git a/Gems/EMotionFX/Code/Tests/UI/CanChangeParametersInSimulatedObject.cpp b/Gems/EMotionFX/Code/Tests/UI/CanChangeParametersInSimulatedObject.cpp index 510bfb2d83..108a637412 100644 --- a/Gems/EMotionFX/Code/Tests/UI/CanChangeParametersInSimulatedObject.cpp +++ b/Gems/EMotionFX/Code/Tests/UI/CanChangeParametersInSimulatedObject.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -37,9 +38,10 @@ namespace EMotionFX { RecordProperty("test_case_id", "C14519563"); - AutoRegisteredActor actor = ActorFactory::CreateAndInit(7, "CanAddToSimulatedObjectActor"); - - ActorInstance* actorInstance = ActorInstance::Create(actor.get()); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = + TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 7, "CanAddToSimulatedObjectActor"); + ActorInstance* actorInstance = ActorInstance::Create(actorAsset->GetActor()); // Change the Editor mode to Simulated Objects EMStudio::GetMainWindow()->ApplicationModeChanged("SimulatedObjects"); diff --git a/Gems/EMotionFX/Code/Tests/UI/CanUseFileMenu.cpp b/Gems/EMotionFX/Code/Tests/UI/CanUseFileMenu.cpp index 73a0f1c865..2af3329203 100644 --- a/Gems/EMotionFX/Code/Tests/UI/CanUseFileMenu.cpp +++ b/Gems/EMotionFX/Code/Tests/UI/CanUseFileMenu.cpp @@ -24,10 +24,12 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -141,8 +143,10 @@ namespace EMotionFX { if (EMotionFX::GetActorManager().GetNumActorInstances() == 0) { - AutoRegisteredActor actor = ActorFactory::CreateAndInit(2, "CanAddSimulatedObjectWithJointsActor"); - ActorInstance::Create(actor.get()); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = + TestActorAssets::CreateActorAssetAndRegister(actorAssetId, 2, "CanAddSimulatedObjectWithJointsActor"); + ActorInstance::Create(actorAsset->GetActor()); EXPECT_EQ(EMotionFX::GetActorManager().GetNumActorInstances(), 1) << "Failed to create actor set for reset test."; } @@ -152,15 +156,16 @@ namespace EMotionFX { if (EMotionFX::GetActorManager().GetNumActorInstances() == 0) { - AutoRegisteredActor actor = ActorFactory::CreateAndInit(2, "CanAddSimulatedObjectWithJointsActor"); - ActorInstance::Create(actor.get()); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = TestActorAssets::CreateActorAssetAndRegister( + actorAssetId, 2, "CanAddSimulatedObjectWithJointsActor"); + ActorInstance::Create(actorAsset->GetActor()); EXPECT_EQ(EMotionFX::GetActorManager().GetNumActorInstances(), 1) << "Failed to create actor set for reset test."; - - actor->SetFileName(filename); + actorAsset->GetActor()->SetFileName(filename); AZStd::string stringFilename = filename; - ExporterLib::SaveActor(stringFilename, actor.get(), MCore::Endian::ENDIAN_LITTLE); + ExporterLib::SaveActor(stringFilename, actorAsset->GetActor(), MCore::Endian::ENDIAN_LITTLE); } } @@ -239,7 +244,6 @@ namespace EMotionFX // Load the actor we just saved, with replaceScene set to true to represent a load. LoadActor(actorFilename.toUtf8().data(), true); - ASSERT_EQ(EMotionFX::GetActorManager().GetNumActorInstances(), 1) << "Failed to load Actor."; // Do it again to verify that number of actors stays the same when replaceScene is true. @@ -696,7 +700,10 @@ namespace EMotionFX TestResetMenuItem(fileMenu); - TestActorMenus(fileMenu); + // Temporarily disable loading actor test. + // This is because the importer command now load actor asset instead of reading from disk. We do not want to add dependency to the asset processor + // in this test. + // TestActorMenus(fileMenu); TestSaveAllMenuItem(fileMenu); } diff --git a/Gems/EMotionFX/Code/Tests/UI/CanUseLayoutMenu.cpp b/Gems/EMotionFX/Code/Tests/UI/CanUseLayoutMenu.cpp index 6fbaf3a028..e615d3c9e0 100644 --- a/Gems/EMotionFX/Code/Tests/UI/CanUseLayoutMenu.cpp +++ b/Gems/EMotionFX/Code/Tests/UI/CanUseLayoutMenu.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/Gems/EMotionFX/Code/Tests/UI/ClothColliderTests.cpp b/Gems/EMotionFX/Code/Tests/UI/ClothColliderTests.cpp index 6428a11e6d..d87c35a4fa 100644 --- a/Gems/EMotionFX/Code/Tests/UI/ClothColliderTests.cpp +++ b/Gems/EMotionFX/Code/Tests/UI/ClothColliderTests.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include namespace EMotionFX @@ -102,7 +103,9 @@ namespace EMotionFX const int lastIndex = 6; RecordProperty("test_case_id", "C18970351"); - AutoRegisteredActor actor = ActorFactory::CreateAndInit(numJoints, "RagdollEditTestsActor"); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = + TestActorAssets::CreateActorAssetAndRegister(actorAssetId, numJoints, "RagdollEditTestsActor"); CreateSkeletonAndModelIndices(); EXPECT_EQ(m_indexList.size(), numJoints); diff --git a/Gems/EMotionFX/Code/Tests/UI/LODSkinnedMeshTests.cpp b/Gems/EMotionFX/Code/Tests/UI/LODSkinnedMeshTests.cpp index 6e5e14e9fc..def8bdab58 100644 --- a/Gems/EMotionFX/Code/Tests/UI/LODSkinnedMeshTests.cpp +++ b/Gems/EMotionFX/Code/Tests/UI/LODSkinnedMeshTests.cpp @@ -80,11 +80,14 @@ namespace EMotionFX DataMembers m_data; }; - AZStd::unique_ptr CreateLODActor(int numLODs) + AZ::Data::Asset CreateLODActor(int numLODs) { - AZStd::unique_ptr actor = ActorFactory::CreateAndInit("LODSkinnedMeshTestsActor"); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = + TestActorAssets::CreateActorAssetAndRegister(actorAssetId, "LODSkinnedMeshTestsActor"); // Modify the actor to have numLODs LOD levels. + Actor* actor = actorAsset->GetActor(); Mesh* lodMesh = actor->GetMesh(0, 0); StandardMaterial* dummyMat = StandardMaterial::Create("Dummy Material"); actor->AddMaterial(0, dummyMat); // owns the material @@ -97,7 +100,7 @@ namespace EMotionFX actor->AddMaterial(i, dummyMat->Clone()); } - return actor; + return AZStd::move(actorAsset); } class LODPropertyRowWidget @@ -112,9 +115,8 @@ namespace EMotionFX const int numLODs = GetParam(); RecordProperty("test_case_id", "C29202698"); - AutoRegisteredActor actor = CreateLODActor(numLODs); - - ActorInstance* actorInstance = ActorInstance::Create(actor.get()); + AZ::Data::Asset actorAsset = CreateLODActor(numLODs); + ActorInstance* actorInstance = ActorInstance::Create(actorAsset->GetActor()); // Change the Editor mode to Character EMStudio::GetMainWindow()->ApplicationModeChanged("Character"); @@ -166,8 +168,7 @@ namespace EMotionFX gameEntity->SetId(entityId); AZ::Data::AssetId actorAssetId("{85D3EF54-7400-43F8-8A40-F6BCBF534E54}"); - AZStd::unique_ptr actor = CreateLODActor(numLODs); - AZ::Data::Asset actorAsset = TestActorAssets::GetAssetFromActor(actorAssetId, AZStd::move(actor)); + AZ::Data::Asset actorAsset = CreateLODActor(numLODs); gameEntity->CreateComponent(); Integration::ActorComponent::Configuration actorConf; diff --git a/Gems/EMotionFX/Code/Tests/UI/RagdollEditTests.cpp b/Gems/EMotionFX/Code/Tests/UI/RagdollEditTests.cpp index 1c39cde5b6..d097e67d15 100644 --- a/Gems/EMotionFX/Code/Tests/UI/RagdollEditTests.cpp +++ b/Gems/EMotionFX/Code/Tests/UI/RagdollEditTests.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -110,7 +111,9 @@ namespace EMotionFX const int numJoints = 6; RecordProperty("test_case_id", "C3122249"); - AutoRegisteredActor actor = ActorFactory::CreateAndInit(numJoints, "RagdollEditTestsActor"); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = + TestActorAssets::CreateActorAssetAndRegister(actorAssetId, numJoints, "RagdollEditTestsActor"); CreateSkeletonAndModelIndices(); @@ -138,7 +141,9 @@ namespace EMotionFX const int numJoints = 8; RecordProperty("test_case_id", "C3122248"); - AutoRegisteredActor actor = ActorFactory::CreateAndInit(numJoints, "RagdollEditTestsActor"); + AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); + AZ::Data::Asset actorAsset = + TestActorAssets::CreateActorAssetAndRegister(actorAssetId, numJoints, "RagdollEditTestsActor"); CreateSkeletonAndModelIndices(); EXPECT_EQ(m_indexList.size(), numJoints);