/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #include "EMotionFX_precompiled.h" #include #include #include namespace EMotionFX { namespace Integration { AZ_CLASS_ALLOCATOR_IMPL(AnimGraphAsset, EMotionFXAllocator, 0) AZ_CLASS_ALLOCATOR_IMPL(AnimGraphAssetHandler, EMotionFXAllocator, 0) AnimGraphAsset::AnimGraphAsset(AZ::Data::AssetId id) : EMotionFXAsset(id) {} AnimGraphAsset::AnimGraphInstancePtr AnimGraphAsset::CreateInstance( EMotionFX::ActorInstance* actorInstance, EMotionFX::MotionSet* motionSet) { AZ_Assert(m_emfxAnimGraph, "Anim graph asset is not loaded"); auto animGraphInstance = EMotionFXPtr::MakeFromNew( EMotionFX::AnimGraphInstance::Create(m_emfxAnimGraph.get(), actorInstance, motionSet)); if (animGraphInstance) { animGraphInstance->SetIsOwnedByRuntime(true); } return animGraphInstance; } void AnimGraphAsset::SetData(EMotionFX::AnimGraph* animGraph) { m_emfxAnimGraph.reset(animGraph); m_status = static_cast(AZ::Data::AssetData::AssetStatus::Ready); } ////////////////////////////////////////////////////////////////////////// bool AnimGraphAssetHandler::OnInitAsset(const AZ::Data::Asset& asset) { AnimGraphAsset* assetData = asset.GetAs(); assetData->m_emfxAnimGraph.reset(EMotionFX::GetImporter().LoadAnimGraph( assetData->m_emfxNativeData.data(), assetData->m_emfxNativeData.size(), nullptr)); if (assetData->m_emfxAnimGraph) { assetData->m_emfxAnimGraph->SetIsOwnedByAsset(true); assetData->m_emfxAnimGraph->SetIsOwnedByRuntime(true); assetData->m_emfxAnimGraph->FindAndRemoveCycles(); // The following code is required to be set so the FileManager detects changes to the files loaded // through this method. Once EMotionFX is integrated to the asset system this can go away. AZStd::string assetFilename; EBUS_EVENT_RESULT(assetFilename, AZ::Data::AssetCatalogRequestBus, GetAssetPathById, asset.GetId()); const char* devAssetsPath = AZ::IO::FileIOBase::GetInstance()->GetAlias("@devassets@"); if (devAssetsPath) { AZStd::string assetSourcePath = devAssetsPath; AzFramework::StringFunc::AssetDatabasePath::Normalize(assetSourcePath); AZStd::string filename; AzFramework::StringFunc::AssetDatabasePath::Join(assetSourcePath.c_str(), assetFilename.c_str(), filename, true); assetData->m_emfxAnimGraph->SetFileName(filename.c_str()); } else { if (GetEMotionFX().GetIsInEditorMode()) { AZ_Warning("EMotionFX", false, "Failed to retrieve asset source path with alias '@devassets@'. Cannot set absolute filename for '%s'", assetFilename.c_str()); } assetData->m_emfxAnimGraph->SetFileName(assetFilename.c_str()); } } AZ_Error("EMotionFX", assetData->m_emfxAnimGraph, "Failed to initialize anim graph asset %s", asset.GetHint().c_str()); return static_cast(assetData->m_emfxAnimGraph); } void AnimGraphAssetHandler::DestroyAsset(AZ::Data::AssetPtr ptr) { AnimGraphAsset* animGraphAsset = static_cast(ptr); EMotionFX::AnimGraph* animGraph = animGraphAsset->GetAnimGraph(); if (animGraph) { // Get rid of all anim graph instances that refer to the anim graph we're about to destroy. EMotionFX::GetAnimGraphManager().RemoveAnimGraphInstances(animGraph); } delete ptr; } ////////////////////////////////////////////////////////////////////////// AZ::Data::AssetType AnimGraphAssetHandler::GetAssetType() const { return azrtti_typeid(); } ////////////////////////////////////////////////////////////////////////// void AnimGraphAssetHandler::GetAssetTypeExtensions(AZStd::vector& extensions) { extensions.push_back("animgraph"); } ////////////////////////////////////////////////////////////////////////// AZ::Uuid AnimGraphAssetHandler::GetComponentTypeId() const { // The system is not in place to allow for components to drive creation of required components // Future work will enable this functionality which will allow dropping in viewport or Inspector panel // EditorAnimGraphComponent // return AZ::Uuid("{770F0A71-59EA-413B-8DAB-235FB0FF1384}"); // Returning null keeps the animgraph from being drag/dropped return AZ::Uuid::CreateNull(); } ////////////////////////////////////////////////////////////////////////// const char* AnimGraphAssetHandler::GetAssetTypeDisplayName() const { return "EMotion FX Anim Graph"; } const char* AnimGraphAssetHandler::GetBrowserIcon() const { return "Editor/Images/AssetBrowser/AnimGraph_16.svg"; } ////////////////////////////////////////////////////////////////////////// void AnimGraphAssetBuilderHandler::InitAsset(const AZ::Data::Asset& asset, bool loadStageSucceeded, bool isReload) { // Don't need to load the referenced animpgraph asset since we only care about the product ID or relative path of the product dependency AZ_UNUSED(asset); AZ_UNUSED(loadStageSucceeded); AZ_UNUSED(isReload); } bool AnimGraphAssetBuilderHandler::LoadAssetData(const AZ::Data::Asset& asset, AZ::IO::GenericStream* stream, const AZ::Data::AssetFilterCB& assetLoadFilterCB) { AZ_UNUSED(asset); AZ_UNUSED(stream); AZ_UNUSED(assetLoadFilterCB); return true; } bool AnimGraphAssetBuilderHandler::LoadAssetData(const AZ::Data::Asset& asset, const char* assetPath, const AZ::Data::AssetFilterCB& assetLoadFilterCB) { AZ_UNUSED(asset); AZ_UNUSED(assetPath); AZ_UNUSED(assetLoadFilterCB); return true; } } // namespace Integration } // namespace EMotionFX