EMotion FX: Root bone not initialized without opening Scene Settings (#2088)

* User provided model was exporting correctly with an .assetinfo while it was not when just placing the .fbx file in the project folder.
* Turned out that the best matching root bone was set by opening the Scene Settings for the first time, so after saving it again it worked correctly.
* We're now chosing the best matching root bone when initializing the actor group, which fixes the issue.

Signed-off-by: Benjamin Jillich <jillich@amazon.com>
This commit is contained in:
Benjamin Jillich
2021-07-12 23:32:35 -07:00
committed by GitHub
parent 158e25bd23
commit 91de09cff5
4 changed files with 28 additions and 1 deletions
@@ -143,6 +143,7 @@ namespace EMotionFX
Group::ActorGroup* group = azrtti_cast<Group::ActorGroup*>(&target);
group->SetName(AZ::SceneAPI::DataTypes::Utilities::CreateUniqueName<Group::IActorGroup>(scene.GetName(), scene.GetManifest()));
group->SetBestMatchingRootBone(scene.GetGraph());
// LOD Rule need to be built first in the actor, so we know which mesh and bone belongs to LOD.
// After this call, LOD rule will be populated with all the LOD bones
@@ -9,10 +9,14 @@
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
#include <SceneAPI/SceneCore/Containers/Views/PairIterator.h>
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphDownwardsIterator.h>
#include <SceneAPI/SceneCore/DataTypes/Rules/IRule.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/IBoneData.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/IMeshData.h>
#include <SceneAPI/SceneCore/DataTypes/Groups/ISceneNodeGroup.h>
#include <SceneAPI/SceneData/GraphData/RootBoneData.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneData/Rules/CoordinateSystemRule.h>
#include <SceneAPIExt/Groups/ActorGroup.h>
@@ -76,6 +80,22 @@ namespace EMotionFX
m_selectedRootBone = selectedRootBone;
}
void ActorGroup::SetBestMatchingRootBone(const AZ::SceneAPI::Containers::SceneGraph& sceneGraph)
{
auto nameContentView = AZ::SceneAPI::Containers::Views::MakePairView(sceneGraph.GetNameStorage(), sceneGraph.GetContentStorage());
auto graphDownwardsView = AZ::SceneAPI::Containers::Views::MakeSceneGraphDownwardsView<AZ::SceneAPI::Containers::Views::BreadthFirst>(
sceneGraph, sceneGraph.GetRoot(), nameContentView.begin(), true);
for (auto it = graphDownwardsView.begin(); it != graphDownwardsView.end(); ++it)
{
if (it->second && it->second->RTTI_IsTypeOf(AZ::SceneData::GraphData::RootBoneData::TYPEINFO_Uuid()))
{
SetSelectedRootBone(it->first.GetPath());
return;
}
}
}
void ActorGroup::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
@@ -45,8 +45,8 @@ namespace EMotionFX
// IActorGroup overrides
const AZStd::string& GetSelectedRootBone() const override;
void SetSelectedRootBone(const AZStd::string& selectedRootBone) override;
void SetBestMatchingRootBone(const AZ::SceneAPI::Containers::SceneGraph& sceneGraph) override;
static void Reflect(AZ::ReflectContext* context);
static bool IActorGroupVersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
@@ -10,6 +10,11 @@
#include <AzCore/RTTI/RTTI.h>
#include <SceneAPI/SceneCore/DataTypes/Groups/IGroup.h>
namespace AZ::SceneAPI::Containers
{
class SceneGraph;
}
namespace EMotionFX
{
namespace Pipeline
@@ -26,6 +31,7 @@ namespace EMotionFX
virtual const AZStd::string& GetSelectedRootBone() const = 0;
virtual void SetSelectedRootBone(const AZStd::string& selectedRootBone) = 0;
virtual void SetBestMatchingRootBone(const AZ::SceneAPI::Containers::SceneGraph& sceneGraph) = 0;
};
}
}