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

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-16 08:53:04 -07:00
committed by GitHub
parent facd1e18b5
commit c1ebbbc176
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;
};
}
}