AnimGraphAsset.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Utils/Utils.h>
  9. #include <Integration/Assets/AnimGraphAsset.h>
  10. #include <EMotionFX/Source/Allocators.h>
  11. #include <EMotionFX/Source/AnimGraphManager.h>
  12. #include <EMotionFX/Source/AnimGraphInstance.h>
  13. #include <EMotionFX/Source/EMotionFXManager.h>
  14. #include <EMotionFX/Source/Importer/Importer.h>
  15. #include <EMotionFX/Source/AnimGraph.h>
  16. namespace EMotionFX
  17. {
  18. namespace Integration
  19. {
  20. AZ_CLASS_ALLOCATOR_IMPL(AnimGraphAsset, EMotionFXAllocator)
  21. AZ_CLASS_ALLOCATOR_IMPL(AnimGraphAssetHandler, EMotionFXAllocator)
  22. AnimGraphAsset::AnimGraphAsset(AZ::Data::AssetId id)
  23. : EMotionFXAsset(id)
  24. {}
  25. AnimGraphAsset::AnimGraphInstancePtr AnimGraphAsset::CreateInstance(
  26. EMotionFX::ActorInstance* actorInstance,
  27. EMotionFX::MotionSet* motionSet)
  28. {
  29. AZ_Assert(m_emfxAnimGraph, "Anim graph asset is not loaded");
  30. auto animGraphInstance = EMotionFXPtr<EMotionFX::AnimGraphInstance>::MakeFromNew(
  31. EMotionFX::AnimGraphInstance::Create(m_emfxAnimGraph.get(), actorInstance, motionSet));
  32. if (animGraphInstance)
  33. {
  34. animGraphInstance->SetIsOwnedByRuntime(true);
  35. }
  36. return animGraphInstance;
  37. }
  38. void AnimGraphAsset::SetData(EMotionFX::AnimGraph* animGraph)
  39. {
  40. m_emfxAnimGraph.reset(animGraph);
  41. m_status = AZ::Data::AssetData::AssetStatus::Ready;
  42. }
  43. //////////////////////////////////////////////////////////////////////////
  44. bool AnimGraphAssetHandler::OnInitAsset(const AZ::Data::Asset<AZ::Data::AssetData>& asset)
  45. {
  46. AnimGraphAsset* assetData = asset.GetAs<AnimGraphAsset>();
  47. assetData->m_emfxAnimGraph.reset(EMotionFX::GetImporter().LoadAnimGraph(
  48. assetData->m_emfxNativeData.data(),
  49. assetData->m_emfxNativeData.size()));
  50. if (assetData->m_emfxAnimGraph)
  51. {
  52. assetData->m_emfxAnimGraph->SetIsOwnedByAsset(true);
  53. assetData->m_emfxAnimGraph->SetIsOwnedByRuntime(true);
  54. assetData->m_emfxAnimGraph->FindAndRemoveCycles();
  55. // The following code is required to be set so the FileManager detects changes to the files loaded
  56. // through this method. Once EMotionFX is integrated to the asset system this can go away.
  57. AZStd::string assetFilename;
  58. AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetFilename, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetPathById, asset.GetId());
  59. AZ::IO::FixedMaxPath projectPath = AZ::Utils::GetProjectPath();
  60. if (!projectPath.empty())
  61. {
  62. AZ::IO::FixedMaxPathString filename{ (projectPath / assetFilename).LexicallyNormal().FixedMaxPathStringAsPosix() };
  63. assetData->m_emfxAnimGraph->SetFileName(filename.c_str());
  64. }
  65. else
  66. {
  67. if (GetEMotionFX().GetIsInEditorMode())
  68. {
  69. AZ_Warning("EMotionFX", false, "Failed to retrieve project root path . Cannot set absolute filename for '%s'", assetFilename.c_str());
  70. }
  71. assetData->m_emfxAnimGraph->SetFileName(assetFilename.c_str());
  72. }
  73. }
  74. assetData->ReleaseEMotionFXData();
  75. AZ_Error("EMotionFX", assetData->m_emfxAnimGraph, "Failed to initialize anim graph asset %s", asset.GetHint().c_str());
  76. return static_cast<bool>(assetData->m_emfxAnimGraph);
  77. }
  78. void AnimGraphAssetHandler::DestroyAsset(AZ::Data::AssetPtr ptr)
  79. {
  80. AnimGraphAsset* animGraphAsset = static_cast<AnimGraphAsset*>(ptr);
  81. EMotionFX::AnimGraph* animGraph = animGraphAsset->GetAnimGraph();
  82. if (animGraph)
  83. {
  84. // Get rid of all anim graph instances that refer to the anim graph we're about to destroy.
  85. EMotionFX::GetAnimGraphManager().RemoveAnimGraphInstances(animGraph);
  86. }
  87. delete ptr;
  88. }
  89. //////////////////////////////////////////////////////////////////////////
  90. AZ::Data::AssetType AnimGraphAssetHandler::GetAssetType() const
  91. {
  92. return azrtti_typeid<AnimGraphAsset>();
  93. }
  94. //////////////////////////////////////////////////////////////////////////
  95. void AnimGraphAssetHandler::GetAssetTypeExtensions(AZStd::vector<AZStd::string>& extensions)
  96. {
  97. extensions.push_back("animgraph");
  98. }
  99. //////////////////////////////////////////////////////////////////////////
  100. AZ::Uuid AnimGraphAssetHandler::GetComponentTypeId() const
  101. {
  102. // The system is not in place to allow for components to drive creation of required components
  103. // Future work will enable this functionality which will allow dropping in viewport or Inspector panel
  104. // EditorAnimGraphComponent
  105. // return AZ::Uuid("{770F0A71-59EA-413B-8DAB-235FB0FF1384}");
  106. // Returning null keeps the animgraph from being drag/dropped
  107. return AZ::Uuid::CreateNull();
  108. }
  109. //////////////////////////////////////////////////////////////////////////
  110. const char* AnimGraphAssetHandler::GetAssetTypeDisplayName() const
  111. {
  112. return "EMotion FX Anim Graph";
  113. }
  114. const char* AnimGraphAssetHandler::GetBrowserIcon() const
  115. {
  116. return "Editor/Images/AssetBrowser/AnimGraph_80.svg";
  117. }
  118. //////////////////////////////////////////////////////////////////////////
  119. void AnimGraphAssetBuilderHandler::InitAsset(const AZ::Data::Asset<AZ::Data::AssetData>& asset, bool loadStageSucceeded, bool isReload)
  120. {
  121. // Don't need to load the referenced animpgraph asset since we only care about the product ID or relative path of the product dependency
  122. AZ_UNUSED(asset);
  123. AZ_UNUSED(loadStageSucceeded);
  124. AZ_UNUSED(isReload);
  125. }
  126. AZ::Data::AssetHandler::LoadResult AnimGraphAssetBuilderHandler::LoadAssetData(
  127. const AZ::Data::Asset<AZ::Data::AssetData>& asset,
  128. AZStd::shared_ptr<AZ::Data::AssetDataStream> stream,
  129. const AZ::Data::AssetFilterCB& assetLoadFilterCB)
  130. {
  131. AZ_UNUSED(asset);
  132. AZ_UNUSED(stream);
  133. AZ_UNUSED(assetLoadFilterCB);
  134. return AZ::Data::AssetHandler::LoadResult::LoadComplete;
  135. }
  136. } // namespace Integration
  137. } // namespace EMotionFX