Integrating github/Helios_RemoveFbxSdk through commit 6dc2604 (#391) (#560)

Removing FBX SDK, LYN-1045. If you have an issues please reach out to the Helios team.
This commit is contained in:
AMZN-stankowi
2021-05-05 09:29:12 -07:00
committed by GitHub
parent 01976a890c
commit a7224b6379
140 changed files with 105 additions and 8639 deletions
@@ -31,9 +31,9 @@ ly_add_target(
AZ::AzFramework
PUBLIC
AZ::AzToolsFramework
AZ::FbxSDKWrapper
AZ::SceneCore
AZ::SceneData
AZ::SDKWrapper
)
ly_add_target(
@@ -31,18 +31,6 @@
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpBlendShapeImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxAnimationImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxBlendShapeImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxBoneImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxColorStreamImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxTangentStreamImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxBitangentStreamImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxMaterialImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxMeshImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxSkinImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxSkinWeightsImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxTransformImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxUvMapImporter.h>
namespace AZ
{
@@ -78,18 +66,6 @@ namespace AZ
g_componentDescriptors.push_back(FbxSceneBuilder::FbxImporter::CreateDescriptor());
// Node and attribute importers
g_componentDescriptors.push_back(FbxAnimationImporter::CreateDescriptor());
g_componentDescriptors.push_back(FbxBlendShapeImporter::CreateDescriptor());
g_componentDescriptors.push_back(FbxBoneImporter::CreateDescriptor());
g_componentDescriptors.push_back(FbxColorStreamImporter::CreateDescriptor());
g_componentDescriptors.push_back(FbxMaterialImporter::CreateDescriptor());
g_componentDescriptors.push_back(FbxMeshImporter::CreateDescriptor());
g_componentDescriptors.push_back(FbxSkinImporter::CreateDescriptor());
g_componentDescriptors.push_back(FbxSkinWeightsImporter::CreateDescriptor());
g_componentDescriptors.push_back(FbxTransformImporter::CreateDescriptor());
g_componentDescriptors.push_back(FbxUvMapImporter::CreateDescriptor());
g_componentDescriptors.push_back(FbxTangentStreamImporter::CreateDescriptor());
g_componentDescriptors.push_back(FbxBitangentStreamImporter::CreateDescriptor());
g_componentDescriptors.push_back(AssImpBitangentStreamImporter::CreateDescriptor());
g_componentDescriptors.push_back(AssImpColorStreamImporter::CreateDescriptor());
g_componentDescriptors.push_back(AssImpMaterialImporter::CreateDescriptor());
@@ -20,13 +20,10 @@
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/FbxImporter.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpMaterialImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/ImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/FbxSDKWrapper/FbxSceneWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxMeshWrapper.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneData/GraphData/TransformData.h>
@@ -55,16 +52,7 @@ namespace AZ
FbxImporter::FbxImporter()
: m_sceneSystem(new FbxSceneSystem())
{
if (m_useAssetImporterSDK)
{
m_sceneWrapper = AZStd::make_unique<AssImpSDKWrapper::AssImpSceneWrapper>();
}
else
{
m_sceneWrapper = AZStd::make_unique<FbxSDKWrapper::FbxSceneWrapper>();
}
m_sceneWrapper = AZStd::make_unique<AssImpSDKWrapper::AssImpSceneWrapper>();
BindToCall(&FbxImporter::ImportProcessing);
}
@@ -89,15 +77,13 @@ namespace AZ
typedef AZStd::function<bool(Containers::Scene & scene)> ConvertFunc;
ConvertFunc convertFunc;
m_sceneSystem->Set(m_sceneWrapper.get());
if (azrtti_istypeof<FbxSDKWrapper::FbxSceneWrapper>(m_sceneWrapper.get()))
if (!azrtti_istypeof<AssImpSDKWrapper::AssImpSceneWrapper>(m_sceneWrapper.get()))
{
convertFunc = AZStd::bind(&FbxImporter::ConvertFbxSceneContext, this, AZStd::placeholders::_1);
}
else
{
convertFunc = AZStd::bind(&FbxImporter::ConvertFbxScene, this, AZStd::placeholders::_1);
return Events::ProcessingResult::Failure;
}
convertFunc = AZStd::bind(&FbxImporter::ConvertFbxScene, this, AZStd::placeholders::_1);
if (convertFunc(context.GetScene()))
{
return Events::ProcessingResult::Success;
@@ -108,175 +94,6 @@ namespace AZ
}
}
bool FbxImporter::ConvertFbxSceneContext(Containers::Scene& scene) const
{
std::shared_ptr<SDKNode::NodeWrapper> fbxRoot = m_sceneWrapper->GetRootNode();
if (!fbxRoot)
{
return false;
}
FbxSDKWrapper::FbxSceneWrapper* fbxSceneWrapper = azrtti_cast <FbxSDKWrapper::FbxSceneWrapper*>(m_sceneWrapper.get());
int sign = 0;
FbxSDKWrapper::FbxAxisSystemWrapper::UpVector upVector = fbxSceneWrapper->GetAxisSystem()->GetUpVector(sign);
AZ_Assert(sign != 0, "sign failed to populate which is a failure in GetUpVector");
if (upVector == FbxSDKWrapper::FbxAxisSystemWrapper::UpVector::Z)
{
if (sign > 0)
{
scene.SetOriginalSceneOrientation(Containers::Scene::SceneOrientation::ZUp);
}
else
{
scene.SetOriginalSceneOrientation(Containers::Scene::SceneOrientation::NegZUp);
AZ_Assert(false, "Negative Z Up scene orientation is not a currently supported orientation.");
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Negative Z Up scene orientation is not a currently supported orientation.");
}
}
else if (upVector == FbxSDKWrapper::FbxAxisSystemWrapper::UpVector::Y)
{
if (sign > 0)
{
scene.SetOriginalSceneOrientation(Containers::Scene::SceneOrientation::YUp);
}
else
{
scene.SetOriginalSceneOrientation(Containers::Scene::SceneOrientation::NegYUp);
AZ_Assert(false, "Negative Y Up scene orientation is not a currently supported orientation.");
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Negative Y Up scene orientation is not a currently supported orientation.");
}
}
else if (upVector == FbxSDKWrapper::FbxAxisSystemWrapper::UpVector::X)
{
if (sign > 0)
{
scene.SetOriginalSceneOrientation(Containers::Scene::SceneOrientation::XUp);
AZ_Assert(false, "Positive X Up scene orientation is not a currently supported orientation.");
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Positive X Up scene orientation is not a currently supported orientation.");
}
else
{
scene.SetOriginalSceneOrientation(Containers::Scene::SceneOrientation::NegXUp);
AZ_Assert(false, "Negative X Up scene orientation is not a currently supported orientation.");
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Negative X Up scene orientation is not a currently supported orientation.");
}
}
AZStd::queue<FbxSceneBuilder::QueueNode> nodes;
nodes.emplace(AZStd::move(fbxRoot), scene.GetGraph().GetRoot());
RenamedNodesMap nodeNameMap;
while (!nodes.empty())
{
FbxSceneBuilder::QueueNode& node = nodes.front();
AZ_Assert(node.m_node, "Empty fbx node queued");
if (!nodeNameMap.RegisterNode(node.m_node, scene.GetGraph(), node.m_parent))
{
AZ_TracePrintf(Utilities::ErrorWindow, "Failed to register fbx node in name table.");
continue;
}
AZStd::string nodeName = nodeNameMap.GetNodeName(node.m_node);
AZ_TraceContext("SceneAPI Node Name", nodeName);
Containers::SceneGraph::NodeIndex newNode = scene.GetGraph().AddChild(node.m_parent, nodeName.c_str());
AZ_Assert(newNode.IsValid(), "Failed to add node to scene graph");
if (!newNode.IsValid())
{
continue;
}
FbxNodeEncounteredContext sourceNodeEncountered(scene, newNode, *fbxSceneWrapper, *m_sceneSystem, nodeNameMap, *azrtti_cast<AZ::FbxSDKWrapper::FbxNodeWrapper*>(node.m_node.get()));
Events::ProcessingResultCombiner nodeResult;
nodeResult += Events::Process(sourceNodeEncountered);
// If no importer created data, we still create an empty node that may eventually contain a transform
if (sourceNodeEncountered.m_createdData.empty())
{
AZ_Assert(nodeResult.GetResult() != Events::ProcessingResult::Success,
"Importers returned success but no data was created");
AZStd::shared_ptr<DataTypes::IGraphObject> nullData(nullptr);
sourceNodeEncountered.m_createdData.emplace_back(nullData);
nodeResult += Events::ProcessingResult::Success;
}
// Create single node since only one piece of graph data was created
if (sourceNodeEncountered.m_createdData.size() == 1)
{
AZ_Assert(nodeResult.GetResult() != Events::ProcessingResult::Ignored,
"An importer created data, but did not return success");
if (nodeResult.GetResult() == Events::ProcessingResult::Failure)
{
AZ_TracePrintf(Utilities::ErrorWindow, "One or more importers failed to create data.");
}
SceneDataPopulatedContext dataProcessed(sourceNodeEncountered,
sourceNodeEncountered.m_createdData[0], nodeName.c_str());
Events::ProcessingResult result = AddDataNodeWithContexts(dataProcessed);
if (result != Events::ProcessingResult::Failure)
{
newNode = dataProcessed.m_currentGraphPosition;
}
}
// Create an empty parent node and place all data under it. The remaining
// tree will be built off of this as the logical parent
else
{
AZ_Assert(nodeResult.GetResult() != Events::ProcessingResult::Ignored,
"%i importers created data, but did not return success",
sourceNodeEncountered.m_createdData.size());
if (nodeResult.GetResult() == Events::ProcessingResult::Failure)
{
AZ_TracePrintf(Utilities::ErrorWindow, "One or more importers failed to create data.");
}
size_t offset = nodeName.length();
for (size_t i = 0; i < sourceNodeEncountered.m_createdData.size(); ++i)
{
nodeName += '_';
nodeName += AZStd::to_string(aznumeric_cast<AZ::u64>(i + 1));
Containers::SceneGraph::NodeIndex subNode =
scene.GetGraph().AddChild(newNode, nodeName.c_str());
AZ_Assert(subNode.IsValid(), "Failed to create new scene sub node");
SceneDataPopulatedContext dataProcessed(sourceNodeEncountered,
sourceNodeEncountered.m_createdData[i], nodeName);
dataProcessed.m_currentGraphPosition = subNode;
AddDataNodeWithContexts(dataProcessed);
// Remove the temporary extension again.
nodeName.erase(offset, nodeName.length() - offset);
}
}
AZ_Assert(nodeResult.GetResult() == Events::ProcessingResult::Success,
"No importers successfully added processed scene data.");
AZ_Assert(newNode != node.m_parent,
"Failed to update current graph position during data processing.");
int childCount = node.m_node->GetChildCount();
for (int i = 0; i < childCount; ++i)
{
std::shared_ptr<FbxSDKWrapper::FbxNodeWrapper> child = std::make_shared<FbxSDKWrapper::FbxNodeWrapper>(node.m_node->GetChild(i)->GetFbxNode());
if (child)
{
nodes.emplace(AZStd::move(child), newNode);
}
}
nodes.pop();
}
Events::ProcessingResult result = Events::Process<FinalizeSceneContext>(scene, *fbxSceneWrapper, *m_sceneSystem, nodeNameMap);
if (result == Events::ProcessingResult::Failure)
{
return false;
}
return true;
}
bool FbxImporter::ConvertFbxScene(Containers::Scene& scene) const
{
std::shared_ptr<SDKNode::NodeWrapper> fbxRoot = m_sceneWrapper->GetRootNode();
@@ -45,13 +45,11 @@ namespace AZ
Events::ProcessingResult ImportProcessing(Events::ImportEventContext& context);
protected:
bool ConvertFbxSceneContext(Containers::Scene& scene) const;
bool ConvertFbxScene(Containers::Scene& scene) const;
void SanitizeNodeName(AZStd::string& nodeName) const;
AZStd::unique_ptr<SDKScene::SceneWrapperBase> m_sceneWrapper;
AZStd::shared_ptr<FbxSceneSystem> m_sceneSystem;
bool m_useAssetImporterSDK = true;
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
@@ -11,8 +11,8 @@
*/
#include <AzCore/Math/Vector3.h>
#include <SceneAPI/FbxSDKWrapper/FbxSceneWrapper.h>
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
#include <assimp/scene.h>
@@ -33,103 +33,86 @@ namespace AZ
void FbxSceneSystem::Set(const SDKScene::SceneWrapperBase* fbxScene)
{
// Get unit conversion factor to meter.
if (azrtti_istypeof<FbxSDKWrapper::FbxSceneWrapper>(fbxScene))
if (!azrtti_istypeof<AssImpSDKWrapper::AssImpSceneWrapper>(fbxScene))
{
const FbxSDKWrapper::FbxSceneWrapper* fbxSDKScene = azrtti_cast <const FbxSDKWrapper::FbxSceneWrapper*>(fbxScene);
m_unitSizeInMeters = fbxSDKScene->GetSystemUnit()->GetConversionFactorTo(FbxSDKWrapper::FbxSystemUnitWrapper::m);
const FbxGlobalSettings& globalSettings = fbxSDKScene->GetFbxScene()->GetGlobalSettings();
m_originalUnitSizeInMeters = static_cast<float>(globalSettings.GetOriginalSystemUnit().GetConversionFactorTo(FbxSystemUnit::m));
int sign = 0;
FbxSDKWrapper::FbxAxisSystemWrapper::UpVector upVector = fbxSDKScene->GetAxisSystem()->GetUpVector(sign);
if (upVector != FbxSDKWrapper::FbxAxisSystemWrapper::Z && upVector != FbxSDKWrapper::FbxAxisSystemWrapper::Unknown)
{
m_adjustTransform.reset(new DataTypes::MatrixType(fbxSDKScene->GetAxisSystem()->CalculateConversionTransform(FbxSDKWrapper::FbxAxisSystemWrapper::Z)));
m_adjustTransformInverse.reset(new DataTypes::MatrixType(m_adjustTransform->GetInverseFull()));
}
return;
}
else if (azrtti_istypeof<AssImpSDKWrapper::AssImpSceneWrapper>(fbxScene))
const AssImpSDKWrapper::AssImpSceneWrapper* assImpScene = azrtti_cast<const AssImpSDKWrapper::AssImpSceneWrapper*>(fbxScene);
// If either meta data piece is not available, the default of 1 will be used.
assImpScene->GetAssImpScene()->mMetaData->Get("UnitScaleFactor", m_unitSizeInMeters);
assImpScene->GetAssImpScene()->mMetaData->Get("OriginalUnitScaleFactor", m_originalUnitSizeInMeters);
/* Conversion factor for converting from centimeters to meters */
m_unitSizeInMeters = m_unitSizeInMeters * .01f;
AZStd::pair<AssImpSDKWrapper::AssImpSceneWrapper::AxisVector, int32_t> upAxisAndSign = assImpScene->GetUpVectorAndSign();
if (upAxisAndSign.second <= 0)
{
const AssImpSDKWrapper::AssImpSceneWrapper* assImpScene = azrtti_cast<const AssImpSDKWrapper::AssImpSceneWrapper*>(fbxScene);
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Negative scene orientation is not a currently supported orientation.");
return;
}
// If either meta data piece is not available, the default of 1 will be used.
assImpScene->GetAssImpScene()->mMetaData->Get("UnitScaleFactor", m_unitSizeInMeters);
assImpScene->GetAssImpScene()->mMetaData->Get("OriginalUnitScaleFactor", m_originalUnitSizeInMeters);
AZStd::pair<AssImpSDKWrapper::AssImpSceneWrapper::AxisVector, int32_t> frontAxisAndSign = assImpScene->GetFrontVectorAndSign();
/* Conversion factor for converting from centimeters to meters */
m_unitSizeInMeters = m_unitSizeInMeters *.01f;
if (upAxisAndSign.first != AssImpSDKWrapper::AssImpSceneWrapper::AxisVector::Z &&
upAxisAndSign.first != AssImpSDKWrapper::AssImpSceneWrapper::AxisVector::Unknown)
{
AZ::Matrix4x4 currentCoordMatrix = AZ::Matrix4x4::CreateIdentity();
//(UpVector = +Z, FrontVector = +Y, CoordSystem = -X(RightHanded))
AZ::Matrix4x4 targetCoordMatrix = AZ::Matrix4x4::CreateFromColumns(
AZ::Vector4(-1, 0, 0, 0),
AZ::Vector4(0, 0, 1, 0),
AZ::Vector4(0, 1, 0, 0),
AZ::Vector4(0, 0, 0, 1));
AZStd::pair<AssImpSDKWrapper::AssImpSceneWrapper::AxisVector, int32_t> upAxisAndSign = assImpScene->GetUpVectorAndSign();
if (upAxisAndSign.second <= 0)
switch (upAxisAndSign.first)
{
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Negative scene orientation is not a currently supported orientation.");
return;
}
AZStd::pair<AssImpSDKWrapper::AssImpSceneWrapper::AxisVector, int32_t> frontAxisAndSign = assImpScene->GetFrontVectorAndSign();
if (upAxisAndSign.first != AssImpSDKWrapper::AssImpSceneWrapper::AxisVector::Z &&
upAxisAndSign.first != AssImpSDKWrapper::AssImpSceneWrapper::AxisVector::Unknown)
{
AZ::Matrix4x4 currentCoordMatrix = AZ::Matrix4x4::CreateIdentity();
//(UpVector = +Z, FrontVector = +Y, CoordSystem = -X(RightHanded))
AZ::Matrix4x4 targetCoordMatrix = AZ::Matrix4x4::CreateFromColumns(
AZ::Vector4(-1, 0, 0, 0),
AZ::Vector4(0, 0, 1, 0),
AZ::Vector4(0, 1, 0, 0),
AZ::Vector4(0, 0, 0, 1));
switch (upAxisAndSign.first)
case AssImpSDKWrapper::AssImpSceneWrapper::AxisVector::X: {
if (frontAxisAndSign.second == 1)
{
case AssImpSDKWrapper::AssImpSceneWrapper::AxisVector::X:
currentCoordMatrix = AZ::Matrix4x4::CreateFromColumns(
AZ::Vector4(0, -1, 0, 0),
AZ::Vector4(1, 0, 0, 0),
AZ::Vector4(0, 0, 1, 0),
AZ::Vector4(0, 0, 0, 1));
}
else
{
if (frontAxisAndSign.second == 1)
{
currentCoordMatrix = AZ::Matrix4x4::CreateFromColumns(
AZ::Vector4(0, -1, 0, 0),
AZ::Vector4(1, 0, 0, 0),
AZ::Vector4(0, 0, 1, 0),
AZ::Vector4(0, 0, 0, 1));
}
else
{
currentCoordMatrix = AZ::Matrix4x4::CreateFromColumns(
AZ::Vector4(0, 1, 0, 0),
AZ::Vector4(1, 0, 0, 0),
AZ::Vector4(0, 0, -1, 0),
AZ::Vector4(0, 0, 0, 1));
}
currentCoordMatrix = AZ::Matrix4x4::CreateFromColumns(
AZ::Vector4(0, 1, 0, 0),
AZ::Vector4(1, 0, 0, 0),
AZ::Vector4(0, 0, -1, 0),
AZ::Vector4(0, 0, 0, 1));
}
break;
case AssImpSDKWrapper::AssImpSceneWrapper::AxisVector::Y:
{
if (frontAxisAndSign.second == 1)
{
currentCoordMatrix = AZ::Matrix4x4::CreateFromColumns(
AZ::Vector4(1, 0, 0, 0),
AZ::Vector4(0, 1, 0, 0),
AZ::Vector4(0, 0, 1, 0),
AZ::Vector4(0, 0, 0, 1));
}
else
{
currentCoordMatrix = AZ::Matrix4x4::CreateFromColumns(
AZ::Vector4(-1, 0, 0, 0),
AZ::Vector4(0, 1, 0, 0),
AZ::Vector4(0, 0, -1, 0),
AZ::Vector4(0, 0, 0, 1));
}
}
break;
}
AZ::Matrix4x4 inverse = currentCoordMatrix.GetInverseTransform();
AZ::Matrix4x4 adjustmatrix = targetCoordMatrix * currentCoordMatrix.GetInverseTransform();
m_adjustTransform.reset(new DataTypes::MatrixType(AssImpSDKWrapper::AssImpTypeConverter::ToTransform(adjustmatrix)));
m_adjustTransformInverse.reset(new DataTypes::MatrixType(m_adjustTransform->GetInverseFull()));
}
break;
case AssImpSDKWrapper::AssImpSceneWrapper::AxisVector::Y: {
if (frontAxisAndSign.second == 1)
{
currentCoordMatrix = AZ::Matrix4x4::CreateFromColumns(
AZ::Vector4(1, 0, 0, 0),
AZ::Vector4(0, 1, 0, 0),
AZ::Vector4(0, 0, 1, 0),
AZ::Vector4(0, 0, 0, 1));
}
else
{
currentCoordMatrix = AZ::Matrix4x4::CreateFromColumns(
AZ::Vector4(-1, 0, 0, 0),
AZ::Vector4(0, 1, 0, 0),
AZ::Vector4(0, 0, -1, 0),
AZ::Vector4(0, 0, 0, 1));
}
}
break;
}
AZ::Matrix4x4 inverse = currentCoordMatrix.GetInverseTransform();
AZ::Matrix4x4 adjustmatrix = targetCoordMatrix * currentCoordMatrix.GetInverseTransform();
m_adjustTransform.reset(new DataTypes::MatrixType(AssImpSDKWrapper::AssImpTypeConverter::ToTransform(adjustmatrix)));
m_adjustTransformInverse.reset(new DataTypes::MatrixType(m_adjustTransform->GetInverseFull()));
}
}
@@ -1,115 +0,0 @@
/*
* 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 <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/SceneCore/Events/ImportEventContext.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
FbxImportContext::FbxImportContext(const FbxSDKWrapper::FbxSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem, FbxSDKWrapper::FbxNodeWrapper& sourceNode)
: m_sourceScene(sourceScene)
, m_sourceSceneSystem(sourceSceneSystem)
, m_sourceNode(sourceNode)
{
}
FbxNodeEncounteredContext::FbxNodeEncounteredContext(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition, const FbxSDKWrapper::FbxSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem, RenamedNodesMap& nodeNameMap, FbxSDKWrapper::FbxNodeWrapper& sourceNode)
: FbxImportContext(sourceScene, sourceSceneSystem, sourceNode)
, NodeEncounteredContext(scene, currentGraphPosition, nodeNameMap)
{
}
FbxNodeEncounteredContext::FbxNodeEncounteredContext(
Events::ImportEventContext& parent, Containers::SceneGraph::NodeIndex currentGraphPosition,
const FbxSDKWrapper::FbxSceneWrapper& sourceScene, const FbxSceneSystem& sourceSceneSystem,
RenamedNodesMap& nodeNameMap, FbxSDKWrapper::FbxNodeWrapper& sourceNode)
: FbxImportContext(sourceScene, sourceSceneSystem, sourceNode)
, NodeEncounteredContext(parent.GetScene(), currentGraphPosition, nodeNameMap)
{
}
SceneDataPopulatedContext::SceneDataPopulatedContext(FbxNodeEncounteredContext& parent,
const AZStd::shared_ptr<DataTypes::IGraphObject>& graphData, const AZStd::string& dataName)
: FbxImportContext(parent.m_sourceScene, parent.m_sourceSceneSystem, parent.m_sourceNode)
, SceneDataPopulatedContextBase(parent, graphData, dataName)
{
}
SceneDataPopulatedContext::SceneDataPopulatedContext(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition, const FbxSDKWrapper::FbxSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem, RenamedNodesMap& nodeNameMap, FbxSDKWrapper::FbxNodeWrapper& sourceNode,
const AZStd::shared_ptr<DataTypes::IGraphObject>& nodeData, const AZStd::string& dataName)
: FbxImportContext(sourceScene, sourceSceneSystem, sourceNode)
, SceneDataPopulatedContextBase(scene, currentGraphPosition, nodeNameMap, nodeData, dataName)
{
}
SceneNodeAppendedContext::SceneNodeAppendedContext(SceneDataPopulatedContext& parent,
Containers::SceneGraph::NodeIndex newIndex)
: FbxImportContext(parent.m_sourceScene, parent.m_sourceSceneSystem, parent.m_sourceNode)
, SceneNodeAppendedContextBase(parent.m_scene, newIndex, parent.m_nodeNameMap)
{
}
SceneNodeAppendedContext::SceneNodeAppendedContext(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition, const FbxSDKWrapper::FbxSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem, RenamedNodesMap& nodeNameMap, FbxSDKWrapper::FbxNodeWrapper& sourceNode)
: FbxImportContext(sourceScene, sourceSceneSystem, sourceNode)
, SceneNodeAppendedContextBase(scene, currentGraphPosition, nodeNameMap)
{
}
SceneAttributeDataPopulatedContext::SceneAttributeDataPopulatedContext(SceneNodeAppendedContext& parent,
const AZStd::shared_ptr<DataTypes::IGraphObject>& nodeData,
const Containers::SceneGraph::NodeIndex attributeNodeIndex, const AZStd::string& dataName)
: FbxImportContext(parent.m_sourceScene, parent.m_sourceSceneSystem, parent.m_sourceNode)
, SceneAttributeDataPopulatedContextBase(parent, nodeData, attributeNodeIndex, dataName)
{
}
SceneAttributeNodeAppendedContext::SceneAttributeNodeAppendedContext(
SceneAttributeDataPopulatedContext& parent, Containers::SceneGraph::NodeIndex newIndex)
: FbxImportContext(parent.m_sourceScene, parent.m_sourceSceneSystem, parent.m_sourceNode)
, SceneAttributeNodeAppendedContextBase(parent, newIndex)
{
}
SceneNodeAddedAttributesContext::SceneNodeAddedAttributesContext(SceneNodeAppendedContext& parent)
: FbxImportContext(parent.m_sourceScene, parent.m_sourceSceneSystem, parent.m_sourceNode)
, SceneNodeAddedAttributesContextBase(parent)
{
}
SceneNodeFinalizeContext::SceneNodeFinalizeContext(SceneNodeAddedAttributesContext& parent)
: FbxImportContext(parent.m_sourceScene, parent.m_sourceSceneSystem, parent.m_sourceNode)
, SceneNodeFinalizeContextBase(parent)
{
}
FinalizeSceneContext::FinalizeSceneContext(Containers::Scene& scene, const FbxSDKWrapper::FbxSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem, RenamedNodesMap& nodeNameMap)
: FinalizeSceneContextBase(scene, nodeNameMap)
, m_sourceScene(sourceScene)
, m_sourceSceneSystem(sourceSceneSystem)
{
}
} // namespace SceneAPI
} // namespace FbxSceneBuilder
} // namespace AZ
@@ -1,184 +0,0 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/std/string/string.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/ImportContexts.h>
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxSceneWrapper;
class FbxNodeWrapper;
}
namespace SceneAPI
{
class FbxSceneSystem;
namespace FbxSceneBuilder
{
class RenamedNodesMap;
// FbxImportContext
// Base structure containing common data needed for all import contexts
// Member Variables:
// m_sourceScene - Basic scene data extracted from the FBX Scene. Used to
// transform data.
// m_sourceNode - FBX node being used for data processing.
struct FbxImportContext
{
AZ_RTTI(FbxImportContext, "{C8D665D5-E871-41AD-90E7-C84CF6842BCF}");
FbxImportContext(const FbxSDKWrapper::FbxSceneWrapper& sourceScene, const FbxSceneSystem& sourceSceneSystem,
FbxSDKWrapper::FbxNodeWrapper& sourceNode);
const FbxSDKWrapper::FbxSceneWrapper& m_sourceScene;
const FbxSceneSystem& m_sourceSceneSystem; // Needed for unit and axis conversion
FbxSDKWrapper::FbxNodeWrapper& m_sourceNode;
};
// FbxNodeEncounteredContext
// Context pushed to indicate that a new FBX Node has been found and any
// importers that have means to process the contained data should do so
// Member Variables:
// m_createdData - out container that importers must add their created data
// to.
struct FbxNodeEncounteredContext
: public FbxImportContext
, public NodeEncounteredContext
{
AZ_RTTI(FbxNodeEncounteredContext, "{BE21E324-6745-41FD-A79C-A6CA7AB15A7A}", FbxImportContext, NodeEncounteredContext);
FbxNodeEncounteredContext(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition, const FbxSDKWrapper::FbxSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem, RenamedNodesMap& nodeNameMap, FbxSDKWrapper::FbxNodeWrapper& sourceNode);
FbxNodeEncounteredContext(Events::ImportEventContext& parent,
Containers::SceneGraph::NodeIndex currentGraphPosition, const FbxSDKWrapper::FbxSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem, RenamedNodesMap& nodeNameMap, FbxSDKWrapper::FbxNodeWrapper& sourceNode);
};
// SceneDataPopulatedContext
// Context pushed to indicate that a piece of scene data has been fully
// processed and any importers that wish to place it within the scene graph
// may now do so. This may be triggered by processing a FbxNodeEncounteredContext
// (for base data, e.g. bones, meshes) or from a SceneNodeAppendedContext
// (for attribute data, e.g. UV Maps, materials)
// Member Variables:
// m_graphData - the piece of data that should be inserted in the graph
// m_dataName - the name that should be used as the basis for the scene node
// name
// m_isAttribute - Indicates whether the graph data is an attribute
struct SceneDataPopulatedContext
: public FbxImportContext
, public SceneDataPopulatedContextBase
{
AZ_RTTI(SceneDataPopulatedContext, "{DF17306C-FE28-4BEB-9CF0-88CF0472B8A8}", FbxImportContext, SceneDataPopulatedContextBase);
SceneDataPopulatedContext(FbxNodeEncounteredContext& parent,
const AZStd::shared_ptr<DataTypes::IGraphObject>& nodeData,
const AZStd::string& dataName);
SceneDataPopulatedContext(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition, const FbxSDKWrapper::FbxSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem, RenamedNodesMap& nodeNameMap, FbxSDKWrapper::FbxNodeWrapper& sourceNode,
const AZStd::shared_ptr<DataTypes::IGraphObject>& nodeData, const AZStd::string& dataName);
};
// SceneNodeAppendedContext
// Context pushed to indicate that data has been added to the scene graph.
// Generally created due to the insertion of a node during SceneDataPopulatedContext
// processing.
struct SceneNodeAppendedContext
: public FbxImportContext
, public SceneNodeAppendedContextBase
{
AZ_RTTI(SceneNodeAppendedContext, "{72C1C37A-C6ED-4CB7-B929-DA03AA44131C}", FbxImportContext, SceneNodeAppendedContextBase);
SceneNodeAppendedContext(SceneDataPopulatedContext& parent, Containers::SceneGraph::NodeIndex newIndex);
SceneNodeAppendedContext(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition, const FbxSDKWrapper::FbxSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem, RenamedNodesMap& nodeNameMap, FbxSDKWrapper::FbxNodeWrapper& sourceNode);
};
// SceneAttributeDataPopulatedContext
// Context pushed to indicate that attribute data has been found and processed
struct SceneAttributeDataPopulatedContext
: public FbxImportContext
, public SceneAttributeDataPopulatedContextBase
{
AZ_RTTI(SceneAttributeDataPopulatedContext, "{93E67C26-5A40-4385-8189-947A626E3CDA}", FbxImportContext, SceneAttributeDataPopulatedContextBase);
SceneAttributeDataPopulatedContext(SceneNodeAppendedContext& parent,
const AZStd::shared_ptr<DataTypes::IGraphObject>& nodeData,
const Containers::SceneGraph::NodeIndex attributeNodeIndex, const AZStd::string& dataName);
};
// SceneAttributeNodeAppendedContext
// Context pushed to indicate that an attribute node has been added to the scene graph
struct SceneAttributeNodeAppendedContext
: public FbxImportContext
, public SceneAttributeNodeAppendedContextBase
{
AZ_RTTI(SceneAttributeNodeAppendedContext, "{C0DD4F39-5C61-4CA0-96C5-9EA3AC40D98B}", FbxImportContext, SceneAttributeNodeAppendedContextBase);
SceneAttributeNodeAppendedContext(SceneAttributeDataPopulatedContext& parent,
Containers::SceneGraph::NodeIndex newIndex);
};
// SceneNodeAddedAttributesContext
// Context pushed to indicate that all attribute processors have completed their
// work for a specific data node.
struct SceneNodeAddedAttributesContext
: public FbxImportContext
, public SceneNodeAddedAttributesContextBase
{
AZ_RTTI(SceneNodeAddedAttributesContext, "{1601900C-5109-4D37-83F1-22317A4D7C78}", FbxImportContext, SceneNodeAddedAttributesContextBase);
SceneNodeAddedAttributesContext(SceneNodeAppendedContext& parent);
};
// SceneNodeFinalizeContext
// Context pushed last after all other contexts for a scene node to allow any
// post-processing needed for an importer.
struct SceneNodeFinalizeContext
: public FbxImportContext
, public SceneNodeFinalizeContextBase
{
AZ_RTTI(SceneNodeFinalizeContext, "{D1D9839A-EA48-425D-BB7A-A9AEA65B8B7A}", FbxImportContext, SceneNodeFinalizeContextBase);
SceneNodeFinalizeContext(SceneNodeAddedAttributesContext& parent);
};
// FinalizeSceneContext
// Context pushed after the scene has been fully created. This can be used to finalize pending work
// such as resolving named links.
struct FinalizeSceneContext
: public FinalizeSceneContextBase
{
AZ_RTTI(FinalizeSceneContext, "{C8D665D5-E871-41AD-90E7-C84CF6842BCF}", FinalizeSceneContextBase);
FinalizeSceneContext(Containers::Scene& scene, const FbxSDKWrapper::FbxSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem, RenamedNodesMap& nodeNameMap);
const FbxSDKWrapper::FbxSceneWrapper& m_sourceScene;
const FbxSceneSystem& m_sourceSceneSystem; // Needed for unit and axis conversion
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -22,11 +22,6 @@
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/FbxSDKWrapper/FbxAnimCurveWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxAnimLayerWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxSceneWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxTimeSpanWrapper.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneData/GraphData/AnimationData.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
@@ -12,8 +12,6 @@
#pragma once
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/FbxSDKWrapper/FbxTimeWrapper.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
@@ -14,13 +14,14 @@
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpBitangentStreamImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/ImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexBitangentData.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <assimp/scene.h>
#include <assimp/mesh.h>
@@ -17,7 +17,7 @@
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpBlendShapeImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/ImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
@@ -17,8 +17,7 @@
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSceneBuilder/Importers/ImporterUtilities.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneData/GraphData/BoneData.h>
#include <SceneAPI/SceneData/GraphData/RootBoneData.h>
@@ -14,13 +14,14 @@
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpColorStreamImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/ImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexColorData.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <assimp/scene.h>
#include <assimp/mesh.h>
@@ -17,7 +17,7 @@
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/ImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
@@ -15,7 +15,7 @@
#include <AzCore/std/string/conversions.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpSkinWeightsImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/ImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/SceneCore/Events/ImportEventContext.h>
@@ -14,13 +14,14 @@
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpTangentStreamImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/ImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexTangentData.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <assimp/scene.h>
#include <assimp/mesh.h>
@@ -15,7 +15,7 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/ImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneData/GraphData/TransformData.h>
@@ -16,12 +16,13 @@
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpUvMapImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/ImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexUVData.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <assimp/scene.h>
#include <assimp/mesh.h>
@@ -1,215 +0,0 @@
/*
* 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 <AzCore/Serialization/SerializeContext.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxAnimationImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxTransformImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxSceneWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxTimeSpanWrapper.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneData/GraphData/BoneData.h>
#include <SceneAPI/SceneData/GraphData/AnimationData.h>
#include <SceneAPI/FbxSDKWrapper/FbxAnimLayerWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxAnimCurveNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxAnimCurveWrapper.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
const char* FbxAnimationImporter::s_animationNodeName = "animation";
const FbxSDKWrapper::FbxTimeWrapper::TimeMode FbxAnimationImporter::s_defaultTimeMode =
FbxSDKWrapper::FbxTimeWrapper::frames30;
FbxAnimationImporter::FbxAnimationImporter()
{
BindToCall(&FbxAnimationImporter::ImportAnimation);
}
void FbxAnimationImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxAnimationImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult FbxAnimationImporter::ImportAnimation(SceneNodeAppendedContext& context)
{
AZ_TraceContext("Importer", "Animation");
// Add check for animation layers at the scene level.
if (context.m_sourceScene.GetAnimationStackCount() <= 0)
{
return Events::ProcessingResult::Ignored;
}
if (context.m_sourceNode.IsMesh())
{
return ImportBlendShapeAnimation(context);
}
if (!context.m_sourceNode.IsBone())
{
return Events::ProcessingResult::Ignored;
}
AZStd::string nodeName = s_animationNodeName;
RenamedNodesMap::SanitizeNodeName(nodeName, context.m_scene.GetGraph(), context.m_currentGraphPosition);
AZ_TraceContext("Animation node name", nodeName);
auto animStackWrapper = context.m_sourceScene.GetAnimationStackAt(0);
const FbxSDKWrapper::FbxTimeWrapper startTime = animStackWrapper->GetLocalTimeSpan().GetStartTime();
const double frameRate = startTime.GetFrameRate();
if (frameRate == 0.0)
{
AZ_TracePrintf(Utilities::ErrorWindow, "Scene has a 0 framerate. Animation cannot be processed without timing information.");
return Events::ProcessingResult::Failure;
}
const int64_t startFrame = startTime.GetFrameCount();
const int64_t numFrames = animStackWrapper->GetLocalTimeSpan().GetNumFrames();
AZStd::shared_ptr<SceneData::GraphData::AnimationData> createdAnimationData =
AZStd::make_shared<SceneData::GraphData::AnimationData>();
createdAnimationData->ReserveKeyFrames(numFrames);
createdAnimationData->SetTimeStepBetweenFrames(1.0 / frameRate);
{
FbxSDKWrapper::FbxTimeWrapper currTime = startTime;
for (int64_t currFrame = startFrame; currFrame < startFrame + numFrames; currFrame++)
{
currTime.SetFrame(currFrame);
SceneAPI::DataTypes::MatrixType animTransform = context.m_sourceNode.EvaluateLocalTransform(currTime);
context.m_sourceSceneSystem.SwapTransformForUpAxis(animTransform);
context.m_sourceSceneSystem.ConvertBoneUnit(animTransform);
createdAnimationData->AddKeyFrame(animTransform);
}
AZ_Assert(createdAnimationData->GetKeyFrameCount() == numFrames, "The imported animation data created does not have the same number of keyframes as the FBX data.");
}
Containers::SceneGraph::NodeIndex addNode = context.m_scene.GetGraph().AddChild(
context.m_currentGraphPosition, nodeName.c_str(), AZStd::move(createdAnimationData));
context.m_scene.GetGraph().MakeEndPoint(addNode);
return Events::ProcessingResult::Success;
}
Events::ProcessingResult FbxAnimationImporter::ImportBlendShapeAnimation(SceneNodeAppendedContext& context)
{
FbxNode * node = context.m_sourceNode.GetFbxNode();
FbxMesh * pMesh = node->GetMesh();
if (!pMesh)
{
return Events::ProcessingResult::Ignored;
}
int deformerCount = pMesh->GetDeformerCount(FbxDeformer::eBlendShape);
int blendShapeIndex = -1;
AZStd::string nodeName;
AZStd::string animNodeName;
for (int deformerIndex = 0; deformerIndex < deformerCount; ++deformerIndex)
{
//we are assuming 1 anim stack (single animation clip export)
const FbxBlendShape* pDeformer = (FbxBlendShape*)pMesh->GetDeformer(deformerIndex, FbxDeformer::eBlendShape);
if (!pDeformer)
{
continue;
}
blendShapeIndex++;
int blendShapeChannelCount = pDeformer->GetBlendShapeChannelCount();
auto animStackWrapper = context.m_sourceScene.GetAnimationStackAt(0);
const FbxSDKWrapper::FbxTimeWrapper startTime = animStackWrapper->GetLocalTimeSpan().GetStartTime();
const double frameRate = startTime.GetFrameRate();
if (frameRate == 0.0)
{
AZ_TracePrintf("Animation_Warning", "Scene has a 0 framerate. Animation cannot be processed without timing information.");
return Events::ProcessingResult::Failure;
}
const int64_t startFrame = startTime.GetFrameCount();
const int64_t numFrames = animStackWrapper->GetLocalTimeSpan().GetNumFrames();
const int layerCount = animStackWrapper->GetAnimationLayerCount();
for (int blendShapeChannelIdx = 0; blendShapeChannelIdx < blendShapeChannelCount; ++blendShapeChannelIdx)
{
const FbxBlendShapeChannel* pChannel = pDeformer->GetBlendShapeChannel(blendShapeChannelIdx);
if (!pChannel)
{
continue;
}
for (int layerIndex = 0; layerIndex < layerCount; layerIndex++)
{
FbxAnimLayer* animationLayer = animStackWrapper->GetAnimationLayerAt(layerIndex)->GetFbxLayer();
FbxAnimCurve* animCurve = pMesh->GetShapeChannel(blendShapeIndex, blendShapeChannelIdx, animationLayer);
if (!animCurve)
{
continue;
}
AZStd::shared_ptr<FbxSDKWrapper::FbxAnimCurveWrapper> animCurveWrapper = AZStd::make_shared<FbxSDKWrapper::FbxAnimCurveWrapper>(animCurve);
AZStd::shared_ptr<SceneData::GraphData::BlendShapeAnimationData> createdAnimationData =
AZStd::make_shared<SceneData::GraphData::BlendShapeAnimationData>();
createdAnimationData->ReserveKeyFrames(numFrames);
createdAnimationData->SetTimeStepBetweenFrames(1.0 / frameRate);
{
FbxSDKWrapper::FbxTimeWrapper currTime = startTime;
for (int64_t currFrame = startFrame; currFrame < startFrame + numFrames; currFrame++)
{
currTime.SetFrame(currFrame);
//weight values from FBX are range 0 - 100
float sampleValue = animCurveWrapper->Evaluate(currTime) / 100.0f;
createdAnimationData->AddKeyFrame(sampleValue);
}
AZ_Assert(createdAnimationData->GetKeyFrameCount() == numFrames, "Imported animation blend data does not contain the same number of keyframes as the source FBX data.")
}
nodeName = pChannel->GetName();
const size_t dotIndex = nodeName.find_last_of('.');
nodeName = nodeName.substr(dotIndex + 1);
createdAnimationData->SetBlendShapeName(nodeName.c_str());
animNodeName = AZStd::string::format("%s_%s", s_animationNodeName, nodeName.c_str());
Containers::SceneGraph::NodeIndex addNode = context.m_scene.GetGraph().AddChild(
context.m_currentGraphPosition, animNodeName.c_str(), AZStd::move(createdAnimationData));
context.m_scene.GetGraph().MakeEndPoint(addNode);
}
}
}
return Events::ProcessingResult::Success;
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,46 +0,0 @@
/*
* 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.
*
*/
#pragma once
#include <fbxsdk.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/FbxSDKWrapper/FbxTimeWrapper.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
class FbxAnimationImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(FbxAnimationImporter, "{26ABDA62-9DB7-4B4D-961D-44B5F5F56808}", SceneCore::LoadingComponent);
FbxAnimationImporter();
~FbxAnimationImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportAnimation(SceneNodeAppendedContext& context);
Events::ProcessingResult ImportBlendShapeAnimation(SceneNodeAppendedContext& context);
protected:
static const char* s_animationNodeName;
static const FbxSDKWrapper::FbxTimeWrapper::TimeMode s_defaultTimeMode;
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,160 +0,0 @@
/*
* 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 <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxBitangentStreamImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxVertexBitangentWrapper.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneData/GraphData/SkinMeshData.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexBitangentData.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneCore/DataTypes/DataTypeUtilities.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
FbxBitangentStreamImporter::FbxBitangentStreamImporter()
{
BindToCall(&FbxBitangentStreamImporter::ImportBitangents);
}
void FbxBitangentStreamImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxBitangentStreamImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult FbxBitangentStreamImporter::ImportBitangents(SceneNodeAppendedContext& context)
{
AZ_TraceContext("Importer", "Bitangents");
std::shared_ptr<FbxSDKWrapper::FbxMeshWrapper> fbxMesh = context.m_sourceNode.GetMesh();
if (!fbxMesh)
{
return Events::ProcessingResult::Ignored;
}
Events::ProcessingResultCombiner combinedStreamResults;
const int numBitangentSets = context.m_sourceNode.GetMesh()->GetElementBitangentCount();
for (int elementIndex = 0; elementIndex < numBitangentSets; ++elementIndex)
{
AZ_TraceContext("Bitangent set index", elementIndex);
FbxSDKWrapper::FbxVertexBitangentWrapper fbxVertexBitangents = fbxMesh->GetElementBitangent(elementIndex);
if (!fbxVertexBitangents.IsValid())
{
AZ_TracePrintf(Utilities::WarningWindow, "Invalid bitangent set found, ignoring");
continue;
}
const AZStd::string originalNodeName = AZStd::string::format("BitangentSet_Fbx_%d", elementIndex);
const AZStd::string nodeName = AZ::SceneAPI::DataTypes::Utilities::CreateUniqueName<SceneData::GraphData::MeshVertexBitangentData>(originalNodeName, context.m_scene.GetManifest());
AZ_TraceContext("Bitangent Set Name", nodeName);
if (originalNodeName != nodeName)
{
AZ_TracePrintf(Utilities::WarningWindow, "Bitangent set '%s' has been renamed to '%s' because the name was already in use.", originalNodeName.c_str(), nodeName.c_str());
}
AZStd::shared_ptr<DataTypes::IGraphObject> parentData = context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
AZ_Assert(parentData && parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()), "Tried to construct bitangent set attribute for invalid or non-mesh parent data");
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
{
combinedStreamResults += Events::ProcessingResult::Failure;
continue;
}
const SceneData::GraphData::MeshData* const parentMeshData = azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
const size_t vertexCount = parentMeshData->GetVertexCount();
AZStd::shared_ptr<SceneData::GraphData::MeshVertexBitangentData> bitangentStream = BuildVertexBitangentData(fbxVertexBitangents, vertexCount, fbxMesh);
AZ_Assert(bitangentStream, "Failed to allocate bitangent data for scene graph.");
if (!bitangentStream)
{
combinedStreamResults += Events::ProcessingResult::Failure;
continue;
}
bitangentStream->SetBitangentSetIndex(elementIndex);
bitangentStream->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::FromFbx);
Containers::SceneGraph::NodeIndex newIndex = context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, nodeName.c_str());
AZ_Assert(newIndex.IsValid(), "Failed to create SceneGraph node for attribute.");
if (!newIndex.IsValid())
{
combinedStreamResults += Events::ProcessingResult::Failure;
continue;
}
Events::ProcessingResult streamResults;
SceneAttributeDataPopulatedContext dataPopulated(context, bitangentStream, newIndex, nodeName);
streamResults = Events::Process(dataPopulated);
if (streamResults != Events::ProcessingResult::Failure)
{
streamResults = AddAttributeDataNodeWithContexts(dataPopulated);
}
combinedStreamResults += streamResults;
}
return combinedStreamResults.GetResult();
}
AZStd::shared_ptr<SceneData::GraphData::MeshVertexBitangentData> FbxBitangentStreamImporter::BuildVertexBitangentData(const FbxSDKWrapper::FbxVertexBitangentWrapper& bitangents, size_t vertexCount, const std::shared_ptr<FbxSDKWrapper::FbxMeshWrapper>& fbxMesh)
{
AZStd::shared_ptr<SceneData::GraphData::MeshVertexBitangentData> bitangentData = AZStd::make_shared<AZ::SceneData::GraphData::MeshVertexBitangentData>();
bitangentData->ReserveContainerSpace(vertexCount);
const int fbxPolygonCount = fbxMesh->GetPolygonCount();
const int* const fbxPolygonVertices = fbxMesh->GetPolygonVertices();
for (int fbxPolygonIndex = 0; fbxPolygonIndex < fbxPolygonCount; ++fbxPolygonIndex)
{
const int fbxPolygonVertexCount = fbxMesh->GetPolygonSize(fbxPolygonIndex);
if (fbxPolygonVertexCount <= 2)
{
continue;
}
const int fbxVertexStartIndex = fbxMesh->GetPolygonVertexIndex(fbxPolygonIndex);
for (int index = 0; index < fbxPolygonVertexCount; ++index)
{
const int fbxPolygonVertexIndex = fbxVertexStartIndex + index;
const int fbxControlPointIndex = fbxPolygonVertices[fbxPolygonVertexIndex];
const Vector3 bitangent = bitangents.GetElementAt(fbxPolygonIndex, fbxPolygonVertexIndex, fbxControlPointIndex);
bitangentData->AppendBitangent(bitangent);
}
}
if (bitangentData->GetCount() != vertexCount)
{
AZ_TracePrintf(Utilities::ErrorWindow, "Vertex count (%i) doesn't match the number of entries for the bitangent stream %s (%i)", vertexCount, bitangents.GetName(), bitangentData->GetCount());
return nullptr;
}
return bitangentData;
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,58 +0,0 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace SceneData
{
namespace GraphData
{
class MeshVertexBitangentData;
}
}
namespace FbxSDKWrapper
{
class FbxMeshWrapper;
class FbxVertexBitangentWrapper;
}
namespace SceneAPI
{
namespace FbxSceneBuilder
{
class FbxBitangentStreamImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(FbxBitangentStreamImporter, "{B68F90E6-9F9D-448F-A874-CABA9F67E5FD}", SceneCore::LoadingComponent);
FbxBitangentStreamImporter();
~FbxBitangentStreamImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportBitangents(SceneNodeAppendedContext& context);
protected:
AZStd::shared_ptr<SceneData::GraphData::MeshVertexBitangentData> BuildVertexBitangentData(const FbxSDKWrapper::FbxVertexBitangentWrapper& bitangents,
size_t vertexCount, const std::shared_ptr<FbxSDKWrapper::FbxMeshWrapper>& fbxMesh);
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,128 +0,0 @@
/*
* 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 <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/std/string/conversions.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxBlendShapeImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/FbxMeshImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxMeshWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxBlendShapeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxBlendShapeChannelWrapper.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneData/GraphData/SkinMeshData.h>
#include <SceneAPI/SceneData/GraphData/BlendShapeData.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
FbxBlendShapeImporter::FbxBlendShapeImporter()
{
BindToCall(&FbxBlendShapeImporter::ImportBlendShapes);
}
void FbxBlendShapeImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxBlendShapeImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult FbxBlendShapeImporter::ImportBlendShapes(SceneNodeAppendedContext& context)
{
AZ_TraceContext("Importer", "Blend Shapes");
if (!IsSkinnedMesh(context.m_sourceNode))
{
return Events::ProcessingResult::Ignored;
}
Events::ProcessingResultCombiner combinedBlendShapeResult;
const std::shared_ptr<FbxSDKWrapper::FbxMeshWrapper> sourceMesh = context.m_sourceNode.GetMesh();
int blendShapeDeformerCount = sourceMesh->GetDeformerCount(FbxDeformer::eBlendShape);
for (int deformerIndex = 0; deformerIndex < blendShapeDeformerCount; ++deformerIndex)
{
AZ_TraceContext("Deformer Index", deformerIndex);
AZStd::shared_ptr<const FbxSDKWrapper::FbxBlendShapeWrapper> fbxBlendShape = sourceMesh->GetBlendShape(deformerIndex);
if (!fbxBlendShape)
{
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Unable to extract BlendShape Deformer at index %d", deformerIndex);
return Events::ProcessingResult::Failure;
}
int blendShapeChannelCount = fbxBlendShape->GetBlendShapeChannelCount();
for (int channelIndex = 0; channelIndex < blendShapeChannelCount; ++channelIndex)
{
//extract the mesh and build a blendshape data object.
AZStd::shared_ptr<const FbxSDKWrapper::FbxBlendShapeChannelWrapper> blendShapeChannel = fbxBlendShape->GetBlendShapeChannel(channelIndex);
int shapeCount = blendShapeChannel->GetTargetShapeCount();
//We do not support percentage blends at this time. Take only the final shape.
AZStd::shared_ptr<const FbxSDKWrapper::FbxMeshWrapper> mesh = blendShapeChannel->GetTargetShape(shapeCount - 1);
if (mesh)
{
//Maya is creating node names of the form cone_skin_blendShapeNode.cone_squash during export.
//We need the name after the period for our naming purposes.
AZStd::string nodeName(blendShapeChannel->GetName());
size_t dotIndex = nodeName.rfind('.');
if (dotIndex != AZStd::string::npos)
{
nodeName.erase(0, dotIndex + 1);
}
RenamedNodesMap::SanitizeNodeName(nodeName, context.m_scene.GetGraph(), context.m_currentGraphPosition, "BlendShape");
AZ_TraceContext("Blend shape name", nodeName);
AZStd::shared_ptr<SceneData::GraphData::BlendShapeData> blendShapeData =
AZStd::make_shared<SceneData::GraphData::BlendShapeData>();
BuildSceneBlendShapeFromFbxBlendShape(blendShapeData, mesh, context.m_sourceSceneSystem);
Containers::SceneGraph::NodeIndex newIndex =
context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, nodeName.c_str());
Events::ProcessingResult blendShapeResult;
SceneAttributeDataPopulatedContext dataPopulated(context, blendShapeData, newIndex, nodeName);
blendShapeResult = Events::Process(dataPopulated);
if (blendShapeResult != Events::ProcessingResult::Failure)
{
blendShapeResult = AddAttributeDataNodeWithContexts(dataPopulated);
}
combinedBlendShapeResult += blendShapeResult;
}
else
{
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Unable to extract blendshape mesh for node '%s' from BlendShapeChannel %d", sourceMesh->GetName(), channelIndex);
combinedBlendShapeResult += Events::ProcessingResult::Failure;
}
}
}
return combinedBlendShapeResult.GetResult();
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,39 +0,0 @@
/*
* 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.
*
*/
#pragma once
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
class FbxBlendShapeImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(FbxBlendShapeImporter, "{3E733F1B-B4A1-4F6F-B2EE-A1C501830E91}", SceneCore::LoadingComponent);
FbxBlendShapeImporter();
~FbxBlendShapeImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportBlendShapes(SceneNodeAppendedContext& context);
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,84 +0,0 @@
/*
* 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 <AzCore/Serialization/SerializeContext.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxBoneImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxTransformImporter.h>
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneData/GraphData/BoneData.h>
#include <SceneAPI/SceneData/GraphData/RootBoneData.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
FbxBoneImporter::FbxBoneImporter()
{
BindToCall(&FbxBoneImporter::ImportBone);
}
void FbxBoneImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxBoneImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult FbxBoneImporter::ImportBone(FbxNodeEncounteredContext& context)
{
AZ_TraceContext("Importer", "Bone");
if (!context.m_sourceNode.IsBone())
{
return Events::ProcessingResult::Ignored;
}
AZStd::shared_ptr<DataTypes::IGraphObject> boneGraphData;
// If the current scene node (our eventual parent) contains bone data, we are not a root bone
AZStd::shared_ptr<SceneData::GraphData::BoneData> createdBoneData;
if (NodeHasAncestorOfType(context.m_scene.GetGraph(), context.m_currentGraphPosition,
DataTypes::IBoneData::TYPEINFO_Uuid()))
{
createdBoneData = AZStd::make_shared<SceneData::GraphData::BoneData>();
}
else
{
createdBoneData = AZStd::make_shared<SceneData::GraphData::RootBoneData>();
}
SceneAPI::DataTypes::MatrixType globalTransform = context.m_sourceNode.EvaluateGlobalTransform();
context.m_sourceSceneSystem.SwapTransformForUpAxis(globalTransform);
context.m_sourceSceneSystem.ConvertBoneUnit(globalTransform);
createdBoneData->SetWorldTransform(globalTransform);
context.m_createdData.push_back(AZStd::move(createdBoneData));
return Events::ProcessingResult::Success;
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,39 +0,0 @@
/*
* 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.
*
*/
#pragma once
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
class FbxBoneImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(FbxBoneImporter, "{3575F356-BC2F-45F6-B57C-9C590ED54995}", SceneCore::LoadingComponent);
FbxBoneImporter();
~FbxBoneImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportBone(FbxNodeEncounteredContext& context);
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,163 +0,0 @@
/*
* 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 <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxColorStreamImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxVertexColorWrapper.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneData/GraphData/SkinMeshData.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexColorData.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
FbxColorStreamImporter::FbxColorStreamImporter()
{
BindToCall(&FbxColorStreamImporter::ImportColorStreams);
}
void FbxColorStreamImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxColorStreamImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult FbxColorStreamImporter::ImportColorStreams(SceneNodeAppendedContext& context)
{
AZ_TraceContext("Importer", "Color Stream");
std::shared_ptr<FbxSDKWrapper::FbxMeshWrapper> fbxMesh =
context.m_sourceNode.GetMesh();
if (!fbxMesh)
{
return Events::ProcessingResult::Ignored;
}
Events::ProcessingResultCombiner combinedVertexColorResults;
for (int i = 0; i < context.m_sourceNode.GetMesh()->GetElementVertexColorCount(); ++i)
{
AZ_TraceContext("Vertex color index", i);
FbxSDKWrapper::FbxVertexColorWrapper fbxVertexColors =
fbxMesh->GetElementVertexColor(i);
if (!fbxVertexColors.IsValid())
{
AZ_TracePrintf(Utilities::WarningWindow, "Invalid vertex color channel found, ignoring");
continue;
}
AZStd::string nodeName = fbxVertexColors.GetName();
RenamedNodesMap::SanitizeNodeName(nodeName, context.m_scene.GetGraph(), context.m_currentGraphPosition, "ColorStream");
AZ_TraceContext("Color Stream Name", nodeName);
AZStd::shared_ptr<DataTypes::IGraphObject> parentData =
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
AZ_Assert(parentData && parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()),
"Tried to construct color stream attribute for invalid or non-mesh parent data");
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
{
combinedVertexColorResults += Events::ProcessingResult::Failure;
continue;
}
SceneData::GraphData::MeshData* parentMeshData =
azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
size_t vertexCount = parentMeshData->GetVertexCount();
AZStd::shared_ptr<SceneData::GraphData::MeshVertexColorData> vertexColors =
BuildVertexColorData(fbxVertexColors, vertexCount, fbxMesh);
AZ_Assert(vertexColors, "Failed to allocate vertex color data for scene graph.");
if (!vertexColors)
{
combinedVertexColorResults += Events::ProcessingResult::Failure;
continue;
}
Containers::SceneGraph::NodeIndex newIndex =
context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, nodeName.c_str());
AZ_Assert(newIndex.IsValid(), "Failed to create SceneGraph node for attribute.");
if (!newIndex.IsValid())
{
combinedVertexColorResults += Events::ProcessingResult::Failure;
continue;
}
Events::ProcessingResult vertexColorResult;
SceneAttributeDataPopulatedContext dataPopulated(context, vertexColors, newIndex, nodeName);
vertexColorResult = AddAttributeDataNodeWithContexts(dataPopulated);
combinedVertexColorResults += vertexColorResult;
}
return combinedVertexColorResults.GetResult();
}
AZStd::shared_ptr<SceneData::GraphData::MeshVertexColorData> FbxColorStreamImporter::BuildVertexColorData(const FbxSDKWrapper::FbxVertexColorWrapper& fbxVertexColors, size_t vertexCount, const std::shared_ptr<FbxSDKWrapper::FbxMeshWrapper>& fbxMesh)
{
AZ_Assert(fbxVertexColors.IsValid(), "BuildVertexColorData was called for invalid color stream data.");
if (!fbxVertexColors.IsValid())
{
return nullptr;
}
AZStd::shared_ptr<SceneData::GraphData::MeshVertexColorData> colorData = AZStd::make_shared<AZ::SceneData::GraphData::MeshVertexColorData>();
colorData->ReserveContainerSpace(vertexCount);
colorData->SetCustomName(fbxVertexColors.GetName());
const int fbxPolygonCount = fbxMesh->GetPolygonCount();
const int* const fbxPolygonVertices = fbxMesh->GetPolygonVertices();
for (int fbxPolygonIndex = 0; fbxPolygonIndex < fbxPolygonCount; ++fbxPolygonIndex)
{
const int fbxPolygonVertexCount = fbxMesh->GetPolygonSize(fbxPolygonIndex);
if (fbxPolygonVertexCount < 3)
{
continue;
}
const int fbxVertexStartIndex = fbxMesh->GetPolygonVertexIndex(fbxPolygonIndex);
for (int polygonVertexIndex = 0; polygonVertexIndex < fbxPolygonVertexCount; ++polygonVertexIndex)
{
const int fbxPolygonVertexIndex = fbxVertexStartIndex + polygonVertexIndex;
const int fbxControlPointIndex = fbxPolygonVertices[fbxPolygonVertexIndex];
FbxSDKWrapper::FbxColorWrapper color = fbxVertexColors.GetElementAt(fbxPolygonIndex, fbxPolygonVertexIndex, fbxControlPointIndex);
colorData->AppendColor({color.GetR(), color.GetG(), color.GetB(), color.GetAlpha()});
}
}
if (colorData->GetCount() != vertexCount)
{
AZ_TracePrintf(Utilities::ErrorWindow, "Vertex count (%i) doesn't match the number of entries for the vertex color stream %s (%i)",
vertexCount, fbxVertexColors.GetName(), colorData->GetCount());
return nullptr;
}
return colorData;
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,57 +0,0 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace SceneData
{
namespace GraphData
{
class MeshVertexColorData;
}
}
namespace FbxSDKWrapper
{
class FbxMeshWrapper;
class FbxVertexColorWrapper;
}
namespace SceneAPI
{
namespace FbxSceneBuilder
{
class FbxColorStreamImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(FbxColorStreamImporter, "{96A25361-04FC-43EC-A443-C81E2E28F3BB}", SceneCore::LoadingComponent);
FbxColorStreamImporter();
~FbxColorStreamImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportColorStreams(SceneNodeAppendedContext& context);
protected:
AZStd::shared_ptr<SceneData::GraphData::MeshVertexColorData> BuildVertexColorData(const FbxSDKWrapper::FbxVertexColorWrapper& fbxVertexColors, size_t vertexCount, const std::shared_ptr<FbxSDKWrapper::FbxMeshWrapper>& fbxMesh);
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,159 +0,0 @@
/*
* 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 <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxMaterialImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxMaterialWrapper.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneData/GraphData/SkinMeshData.h>
#include <SceneAPI/SceneData/GraphData/MaterialData.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
FbxMaterialImporter::FbxMaterialImporter()
{
BindToCall(&FbxMaterialImporter::ImportMaterials);
}
void FbxMaterialImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxMaterialImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult FbxMaterialImporter::ImportMaterials(SceneNodeAppendedContext& context)
{
AZ_TraceContext("Importer", "Material");
if (!context.m_sourceNode.GetMesh())
{
return Events::ProcessingResult::Ignored;
}
Events::ProcessingResultCombiner combinedMaterialImportResults;
for (int materialIndex = 0; materialIndex < context.m_sourceNode.GetMaterialCount(); ++materialIndex)
{
AZ_TraceContext("Material Index", materialIndex);
const std::shared_ptr<FbxSDKWrapper::FbxMaterialWrapper> fbxMaterial =
context.m_sourceNode.GetMaterial(materialIndex);
if (!fbxMaterial)
{
AZ_TracePrintf(Utilities::WarningWindow, "Invalid material data found, ignoring.");
continue;
}
AZStd::string materialName = fbxMaterial->GetName().c_str();
RenamedNodesMap::SanitizeNodeName(materialName, context.m_scene.GetGraph(), context.m_currentGraphPosition, "Material");
AZ_TraceContext("Material Name", materialName);
AZStd::shared_ptr<SceneData::GraphData::MaterialData> materialData =
BuildMaterial(context.m_sourceNode, materialIndex);
AZ_Assert(materialData, "Failed to allocate scene material data.");
if (!materialData)
{
combinedMaterialImportResults += Events::ProcessingResult::Failure;
continue;
}
Events::ProcessingResult materialResult;
Containers::SceneGraph::NodeIndex newIndex =
context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, materialName.c_str());
AZ_Assert(newIndex.IsValid(), "Failed to create SceneGraph node for attribute.");
if(!newIndex.IsValid())
{
combinedMaterialImportResults += Events::ProcessingResult::Failure;
continue;
}
SceneAttributeDataPopulatedContext dataPopulated(context, materialData, newIndex, materialName);
materialResult = Events::Process(dataPopulated);
if (materialResult != Events::ProcessingResult::Failure)
{
materialResult = AddAttributeDataNodeWithContexts(dataPopulated);
}
combinedMaterialImportResults += materialResult;
}
return combinedMaterialImportResults.GetResult();
}
AZStd::shared_ptr<SceneData::GraphData::MaterialData> FbxMaterialImporter::BuildMaterial(FbxSDKWrapper::FbxNodeWrapper& node, int materialIndex) const
{
AZ_Assert(materialIndex < node.GetMaterialCount(), "Invalid material index (%i)", materialIndex);
const std::shared_ptr<FbxSDKWrapper::FbxMaterialWrapper> fbxMaterial = node.GetMaterial(materialIndex);
if (!fbxMaterial)
{
return nullptr;
}
AZStd::shared_ptr<SceneData::GraphData::MaterialData> material = AZStd::make_shared<SceneData::GraphData::MaterialData>();
material->SetMaterialName(fbxMaterial->GetName());
material->SetTexture(DataTypes::IMaterialData::TextureMapType::Diffuse,
fbxMaterial->GetTextureFileName(FbxSDKWrapper::FbxMaterialWrapper::MaterialMapType::Diffuse).c_str());
material->SetTexture(DataTypes::IMaterialData::TextureMapType::Specular,
fbxMaterial->GetTextureFileName(FbxSDKWrapper::FbxMaterialWrapper::MaterialMapType::Specular).c_str());
material->SetTexture(DataTypes::IMaterialData::TextureMapType::Bump,
fbxMaterial->GetTextureFileName(FbxSDKWrapper::FbxMaterialWrapper::MaterialMapType::Bump).c_str());
material->SetTexture(DataTypes::IMaterialData::TextureMapType::Normal,
fbxMaterial->GetTextureFileName(FbxSDKWrapper::FbxMaterialWrapper::MaterialMapType::Normal).c_str());
material->SetDiffuseColor(fbxMaterial->GetDiffuseColor());
material->SetSpecularColor(fbxMaterial->GetSpecularColor());
material->SetEmissiveColor(fbxMaterial->GetEmissiveColor());
material->SetShininess(fbxMaterial->GetShininess());
float opacity = fbxMaterial->GetOpacity();
if (opacity == 0.0f)
{
opacity = 1.0f;
AZ_TracePrintf(Utilities::WarningWindow, "Opacity has been changed from 0 to full. Some DCC tools ignore the opacity and "
"write 0 to indicate opacity is not used. This causes meshes to turn invisible, which is often not the intention so "
"the opacity has been set to full automatically. If the intention was for a fully transparent mesh, please update "
"the opacity in Open 3D Engine's material editor.");
}
material->SetOpacity(opacity);
// Due to the fact that fbxMaterial->GetUniqueId() will return a different ID
// each time when the fbx is reprocessed, we need a more stable ID.
// The current best candidate is probably the name of the material.
// But this will also force the user to update the material component for overrides
// if the fbx material name is changed outside from apps like dcc tools.
// (Ideally, only changing the material properties in the dcc tool will force the user to update the material component)
//
// Using 32-bit CRC as it is mathematically stable and enough within the same fbx.
uint64_t id = uint32_t(AZ::Crc32(fbxMaterial->GetName()));
material->SetUniqueId(id);
return material;
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,51 +0,0 @@
/*
* 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.
*
*/
#pragma once
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/SceneCore/Events/ProcessingResult.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace SceneData
{
namespace GraphData
{
class MaterialData;
}
}
namespace SceneAPI
{
namespace FbxSceneBuilder
{
class FbxMaterialImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(FbxMaterialImporter, "{E1DF4182-793D-4188-B833-1236D33CCEB4}", SceneCore::LoadingComponent);
FbxMaterialImporter();
~FbxMaterialImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportMaterials(SceneNodeAppendedContext& context);
protected:
AZStd::shared_ptr<SceneData::GraphData::MaterialData> BuildMaterial(FbxSDKWrapper::FbxNodeWrapper& node, int materialIndex) const;
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,69 +0,0 @@
/*
* 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 <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxMeshImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/FbxMeshImporterUtilities.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxMeshWrapper.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
FbxMeshImporter::FbxMeshImporter()
{
BindToCall(&FbxMeshImporter::ImportMesh);
}
void FbxMeshImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxMeshImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult FbxMeshImporter::ImportMesh(FbxNodeEncounteredContext& context)
{
AZ_TraceContext("Importer", "Mesh");
if (!context.m_sourceNode.GetMesh() ||
IsSkinnedMesh(context.m_sourceNode))
{
return Events::ProcessingResult::Ignored;
}
AZStd::shared_ptr<SceneData::GraphData::MeshData> createdData =
AZStd::make_shared<SceneData::GraphData::MeshData>();
if (BuildSceneMeshFromFbxMesh(createdData, *context.m_sourceNode.GetMesh(), context.m_sourceSceneSystem))
{
context.m_createdData.push_back(std::move(createdData));
return Events::ProcessingResult::Success;
}
else
{
return Events::ProcessingResult::Failure;
}
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,54 +0,0 @@
/*
* 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.
*
*/
#pragma once
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxMeshWrapper;
}
namespace SceneData
{
namespace GraphData
{
class MeshData;
}
}
namespace SceneAPI
{
class FbxSceneSystem;
namespace FbxSceneBuilder
{
class FbxMeshImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(FbxMeshImporter, "{8D131E77-4D53-486A-B3C6-80ACC27A6D50}", SceneCore::LoadingComponent);
FbxMeshImporter();
~FbxMeshImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportMesh(FbxNodeEncounteredContext& context);
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,69 +0,0 @@
/*
* 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 <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxSkinImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/FbxMeshImporterUtilities.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxMeshWrapper.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneData/GraphData/SkinMeshData.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
FbxSkinImporter::FbxSkinImporter()
{
BindToCall(&FbxSkinImporter::ImportSkin);
}
void FbxSkinImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxSkinImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult FbxSkinImporter::ImportSkin(FbxNodeEncounteredContext& context)
{
if (!context.m_sourceNode.GetMesh() ||
!IsSkinnedMesh(context.m_sourceNode))
{
return Events::ProcessingResult::Ignored;
}
AZStd::shared_ptr<SceneData::GraphData::SkinMeshData> createdData =
AZStd::make_shared<SceneData::GraphData::SkinMeshData>();
if (BuildSceneMeshFromFbxMesh(createdData, *context.m_sourceNode.GetMesh(), context.m_sourceSceneSystem))
{
context.m_createdData.push_back(std::move(createdData));
return Events::ProcessingResult::Success;
}
else
{
return Events::ProcessingResult::Failure;
}
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,39 +0,0 @@
/*
* 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.
*
*/
#pragma once
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
class FbxSkinImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(FbxSkinImporter, "{22108E92-7037-442D-94E0-A2E92554A79F}", SceneCore::LoadingComponent);
FbxSkinImporter();
~FbxSkinImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportSkin(FbxNodeEncounteredContext& context);
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,177 +0,0 @@
/*
* 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 <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/std/string/conversions.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxSkinWeightsImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/FbxSDKWrapper/FbxMeshWrapper.h>
#include <SceneAPI/SceneCore/Events/ImportEventContext.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneData/GraphData/SkinMeshData.h>
#include <SceneAPI/SceneData/GraphData/SkinWeightData.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
const AZStd::string FbxSkinWeightsImporter::s_skinWeightName = "SkinWeight_";
FbxSkinWeightsImporter::FbxSkinWeightsImporter()
{
BindToCall(&FbxSkinWeightsImporter::ImportSkinWeights);
BindToCall(&FbxSkinWeightsImporter::SetupNamedBoneLinks);
}
void FbxSkinWeightsImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxSkinWeightsImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult FbxSkinWeightsImporter::ImportSkinWeights(SceneNodeAppendedContext& context)
{
AZ_TraceContext("Importer", "Skin Weights");
if (!IsSkinnedMesh(context.m_sourceNode))
{
return Events::ProcessingResult::Ignored;
}
Events::ProcessingResultCombiner combinedSkinWeightsResult;
for (int deformerIndex = 0; deformerIndex < context.m_sourceNode.GetMesh()->GetDeformerCount(FbxDeformer::eSkin); ++deformerIndex)
{
AZ_TraceContext("Deformer Index", deformerIndex);
AZStd::shared_ptr<const FbxSDKWrapper::FbxSkinWrapper> fbxSkin =
context.m_sourceNode.GetMesh()->GetSkin(deformerIndex);
if (!fbxSkin)
{
return Events::ProcessingResult::Failure;
}
AZStd::string skinWeightName = s_skinWeightName;
skinWeightName += AZStd::to_string(deformerIndex);
RenamedNodesMap::SanitizeNodeName(skinWeightName, context.m_scene.GetGraph(), context.m_currentGraphPosition);
AZStd::shared_ptr<SceneData::GraphData::SkinWeightData> skinDeformer =
BuildSkinWeightData(context.m_sourceNode.GetMesh(), deformerIndex);
AZ_Assert(skinDeformer, "Failed to allocate skin weighting data.");
if (!skinDeformer)
{
combinedSkinWeightsResult += Events::ProcessingResult::Failure;
continue;
}
Containers::SceneGraph::NodeIndex newIndex =
context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, skinWeightName.c_str());
AZ_Assert(newIndex.IsValid(), "Failed to create SceneGraph node for attribute.");
if (!newIndex.IsValid())
{
combinedSkinWeightsResult += Events::ProcessingResult::Failure;
continue;
}
Events::ProcessingResult skinWeightsResult;
SceneAttributeDataPopulatedContext dataPopulated(context, skinDeformer, newIndex, skinWeightName);
skinWeightsResult = Events::Process(dataPopulated);
if (skinWeightsResult != Events::ProcessingResult::Failure)
{
skinWeightsResult = AddAttributeDataNodeWithContexts(dataPopulated);
}
combinedSkinWeightsResult += skinWeightsResult;
}
return combinedSkinWeightsResult.GetResult();
}
AZStd::shared_ptr<SceneData::GraphData::SkinWeightData> FbxSkinWeightsImporter::BuildSkinWeightData(
const std::shared_ptr<const FbxSDKWrapper::FbxMeshWrapper>& fbxMesh, int skinIndex)
{
AZStd::shared_ptr<const FbxSDKWrapper::FbxSkinWrapper> fbxSkin = fbxMesh->GetSkin(skinIndex);
AZ_Assert(fbxSkin, "BuildSkinWeightData was called for index %i which doesn't contain a skin deformer.",
skinIndex);
if (!fbxSkin)
{
return nullptr;
}
AZStd::shared_ptr<SceneData::GraphData::SkinWeightData> skinWeightData =
AZStd::make_shared<SceneData::GraphData::SkinWeightData>();
// Cache the new object and the link info for now so it can be resolved at a later point when all
// names have been updated.
Pending pending;
pending.m_fbxMesh = fbxMesh;
pending.m_fbxSkin = fbxSkin;
pending.m_skinWeightData = skinWeightData;
m_pendingSkinWeights.push_back(pending);
return skinWeightData;
}
Events::ProcessingResult FbxSkinWeightsImporter::SetupNamedBoneLinks(FinalizeSceneContext& context)
{
AZ_TraceContext("Importer", "Skin Weights");
for (auto& it : m_pendingSkinWeights)
{
int controlPointCount = it.m_fbxMesh->GetControlPointsCount();
it.m_skinWeightData->ResizeContainerSpace(controlPointCount);
int clusterCount = it.m_fbxSkin->GetClusterCount();
for (int clusterIndex = 0; clusterIndex < clusterCount; ++clusterIndex)
{
int controlPointCount2 = it.m_fbxSkin->GetClusterControlPointIndicesCount(clusterIndex);
AZStd::shared_ptr<const FbxSDKWrapper::FbxNodeWrapper> fbxLink = it.m_fbxSkin->GetClusterLink(clusterIndex);
if (!fbxLink)
{
AZ_TracePrintf(Utilities::WarningWindow, "FBX data contains null skin cluster link at index %i", clusterIndex);
continue;
}
// The name of the bones may be updated as they get processed. Processing of bones may not necessarily happen before
// processing skin weights so to avoid storing names that will be updated later delay setting up the link until
// all processing has completed.
AZStd::string boneName = context.m_nodeNameMap.GetNodeName(fbxLink);
int boneId = it.m_skinWeightData->GetBoneId(boneName);
for (int pointIndex = 0; pointIndex < controlPointCount2; ++pointIndex)
{
SceneAPI::DataTypes::ISkinWeightData::Link link;
link.boneId = boneId;
link.weight = aznumeric_caster(it.m_fbxSkin->GetClusterControlPointWeight(clusterIndex, pointIndex));
it.m_skinWeightData->AppendLink(it.m_fbxSkin->GetClusterControlPointIndex(clusterIndex, pointIndex), link);
}
}
}
const auto result = m_pendingSkinWeights.empty() ? Events::ProcessingResult::Ignored : Events::ProcessingResult::Success;
m_pendingSkinWeights.clear();
return result;
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,79 +0,0 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/std/containers/vector.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/ISkinWeightData.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxMeshWrapper;
}
namespace SceneData
{
namespace GraphData
{
class SkinWeightData;
}
}
namespace SceneAPI
{
namespace Events
{
class PostImportEventContext;
}
namespace FbxSceneBuilder
{
class FbxSkinWeightsImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(FbxSkinWeightsImporter, "{95FCD291-5E1F-4591-90AD-AB5EA2599C3E}", SceneCore::LoadingComponent);
FbxSkinWeightsImporter();
~FbxSkinWeightsImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportSkinWeights(SceneNodeAppendedContext& context);
Events::ProcessingResult SetupNamedBoneLinks(FinalizeSceneContext& context);
protected:
struct Pending
{
std::shared_ptr<const FbxSDKWrapper::FbxMeshWrapper> m_fbxMesh;
AZStd::shared_ptr<const FbxSDKWrapper::FbxSkinWrapper> m_fbxSkin;
AZStd::shared_ptr<SceneData::GraphData::SkinWeightData> m_skinWeightData;
};
AZStd::shared_ptr<SceneData::GraphData::SkinWeightData> BuildSkinWeightData(
const std::shared_ptr<const FbxSDKWrapper::FbxMeshWrapper>& fbxMesh, int skinIndex);
//! List of skin weights that still need to be filled in. Setting the data for skin weights is
//! delayed until after the tree has been fully constructed as bones are linked by name, but until
//! the graph has been fully filled in, those names can change which would break the names recorded
//! for the skin.
AZStd::vector<Pending> m_pendingSkinWeights;
static const AZStd::string s_skinWeightName;
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,162 +0,0 @@
/*
* 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 <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxTangentStreamImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxVertexTangentWrapper.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneData/GraphData/SkinMeshData.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexTangentData.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneCore/DataTypes/DataTypeUtilities.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
FbxTangentStreamImporter::FbxTangentStreamImporter()
{
BindToCall(&FbxTangentStreamImporter::ImportTangents);
}
void FbxTangentStreamImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxTangentStreamImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult FbxTangentStreamImporter::ImportTangents(SceneNodeAppendedContext& context)
{
AZ_TraceContext("Importer", "Tangents");
std::shared_ptr<FbxSDKWrapper::FbxMeshWrapper> fbxMesh = context.m_sourceNode.GetMesh();
if (!fbxMesh)
{
return Events::ProcessingResult::Ignored;
}
Events::ProcessingResultCombiner combinedStreamResults;
const int numTangentSets = context.m_sourceNode.GetMesh()->GetElementTangentCount();
for (int elementIndex = 0; elementIndex < numTangentSets; ++elementIndex)
{
AZ_TraceContext("Tangent set index", elementIndex);
FbxSDKWrapper::FbxVertexTangentWrapper fbxVertexTangents = fbxMesh->GetElementTangent(elementIndex);
if (!fbxVertexTangents.IsValid())
{
AZ_TracePrintf(Utilities::WarningWindow, "Invalid tangent set found, ignoring");
continue;
}
const AZStd::string originalNodeName = AZStd::string::format("TangentSet_Fbx_%d", elementIndex);
const AZStd::string nodeName = AZ::SceneAPI::DataTypes::Utilities::CreateUniqueName<SceneData::GraphData::MeshVertexTangentData>(originalNodeName, context.m_scene.GetManifest());
AZ_TraceContext("Tangent Set Name", nodeName);
if (originalNodeName != nodeName)
{
AZ_TracePrintf(Utilities::WarningWindow, "Tangent set '%s' has been renamed to '%s' because the name was already in use.", originalNodeName.c_str(), nodeName.c_str());
}
AZStd::shared_ptr<DataTypes::IGraphObject> parentData = context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
AZ_Assert(parentData && parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()), "Tried to construct tangent set attribute for invalid or non-mesh parent data");
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
{
combinedStreamResults += Events::ProcessingResult::Failure;
continue;
}
const SceneData::GraphData::MeshData* const parentMeshData = azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
const size_t vertexCount = parentMeshData->GetVertexCount();
AZStd::shared_ptr<SceneData::GraphData::MeshVertexTangentData> tangentStream = BuildVertexTangentData(fbxVertexTangents, vertexCount, fbxMesh);
AZ_Assert(tangentStream, "Failed to allocate tangent data for scene graph.");
if (!tangentStream)
{
combinedStreamResults += Events::ProcessingResult::Failure;
continue;
}
tangentStream->SetTangentSetIndex(elementIndex);
tangentStream->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::FromFbx);
const Containers::SceneGraph::NodeIndex newIndex = context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, nodeName.c_str());
AZ_Assert(newIndex.IsValid(), "Failed to create SceneGraph node for attribute.");
if (!newIndex.IsValid())
{
combinedStreamResults += Events::ProcessingResult::Failure;
continue;
}
Events::ProcessingResult streamResults;
SceneAttributeDataPopulatedContext dataPopulated(context, tangentStream, newIndex, nodeName);
streamResults = Events::Process(dataPopulated);
if (streamResults != Events::ProcessingResult::Failure)
{
streamResults = AddAttributeDataNodeWithContexts(dataPopulated);
}
combinedStreamResults += streamResults;
}
return combinedStreamResults.GetResult();
}
AZStd::shared_ptr<SceneData::GraphData::MeshVertexTangentData> FbxTangentStreamImporter::BuildVertexTangentData(const FbxSDKWrapper::FbxVertexTangentWrapper& tangents, size_t vertexCount, const std::shared_ptr<FbxSDKWrapper::FbxMeshWrapper>& fbxMesh)
{
AZStd::shared_ptr<SceneData::GraphData::MeshVertexTangentData> tangentData = AZStd::make_shared<AZ::SceneData::GraphData::MeshVertexTangentData>();
tangentData->ReserveContainerSpace(vertexCount);
const int fbxPolygonCount = fbxMesh->GetPolygonCount();
const int* const fbxPolygonVertices = fbxMesh->GetPolygonVertices();
for (int fbxPolygonIndex = 0; fbxPolygonIndex < fbxPolygonCount; ++fbxPolygonIndex)
{
const int fbxPolygonVertexCount = fbxMesh->GetPolygonSize(fbxPolygonIndex);
if (fbxPolygonVertexCount <= 2)
{
continue;
}
const int fbxVertexStartIndex = fbxMesh->GetPolygonVertexIndex(fbxPolygonIndex);
for (int index = 0; index < fbxPolygonVertexCount; ++index)
{
const int fbxPolygonVertexIndex = fbxVertexStartIndex + index;
const int fbxControlPointIndex = fbxPolygonVertices[fbxPolygonVertexIndex];
const Vector3 tangent = tangents.GetElementAt(fbxPolygonIndex, fbxPolygonVertexIndex, fbxControlPointIndex);
tangentData->AppendTangent(AZ::Vector4(tangent.GetX(), tangent.GetY(), tangent.GetZ(), 1.0f));
}
}
if (tangentData->GetCount() != vertexCount)
{
AZ_TracePrintf(Utilities::ErrorWindow, "Vertex count (%i) doesn't match the number of entries for the tangent stream %s (%i)", vertexCount, tangents.GetName(), tangentData->GetCount());
return nullptr;
}
return tangentData;
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,58 +0,0 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace SceneData
{
namespace GraphData
{
class MeshVertexTangentData;
}
}
namespace FbxSDKWrapper
{
class FbxMeshWrapper;
class FbxVertexTangentWrapper;
}
namespace SceneAPI
{
namespace FbxSceneBuilder
{
class FbxTangentStreamImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(FbxTangentStreamImporter, "{70F3A9F5-5BB1-4FE2-BD63-A60C2DCA4589}", SceneCore::LoadingComponent);
FbxTangentStreamImporter();
~FbxTangentStreamImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportTangents(SceneNodeAppendedContext& context);
protected:
AZStd::shared_ptr<SceneData::GraphData::MeshVertexTangentData> BuildVertexTangentData(const FbxSDKWrapper::FbxVertexTangentWrapper& tangents,
size_t vertexCount, const std::shared_ptr<FbxSDKWrapper::FbxMeshWrapper>& fbxMesh);
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,121 +0,0 @@
/*
* 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 <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxTransformImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneData/GraphData/TransformData.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
const char* FbxTransformImporter::s_transformNodeName = "transform";
FbxTransformImporter::FbxTransformImporter()
{
BindToCall(&FbxTransformImporter::ImportTransform);
}
void FbxTransformImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxTransformImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult FbxTransformImporter::ImportTransform(SceneNodeAppendedContext& context)
{
AZ_TraceContext("Importer", "Transform");
DataTypes::MatrixType localTransform;
if (!GetBindPoseLocalTransform(context.m_sourceScene, context.m_sourceNode, localTransform))
{
localTransform = context.m_sourceNode.EvaluateLocalTransform();
DataTypes::MatrixType geoTransform = context.m_sourceNode.GetGeometricTransform(); // transform of the pivot
localTransform *= geoTransform;
}
if (localTransform == DataTypes::MatrixType::Identity())
{
return Events::ProcessingResult::Ignored;
}
context.m_sourceSceneSystem.SwapTransformForUpAxis(localTransform);
context.m_sourceSceneSystem.ConvertUnit(localTransform);
AZStd::shared_ptr<SceneData::GraphData::TransformData> transformData =
AZStd::make_shared<SceneData::GraphData::TransformData>(localTransform);
AZ_Assert(transformData, "Failed to allocate transform data.");
if (!transformData)
{
return Events::ProcessingResult::Failure;
}
// If it is non-endpoint data populated node, add a transform attribute
if (context.m_scene.GetGraph().HasNodeContent(context.m_currentGraphPosition))
{
if (!context.m_scene.GetGraph().IsNodeEndPoint(context.m_currentGraphPosition))
{
AZStd::string nodeName = s_transformNodeName;
RenamedNodesMap::SanitizeNodeName(nodeName, context.m_scene.GetGraph(), context.m_currentGraphPosition);
AZ_TraceContext("Transform node name", nodeName);
Containers::SceneGraph::NodeIndex newIndex =
context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, nodeName.c_str());
AZ_Assert(newIndex.IsValid(), "Failed to create SceneGraph node for attribute.");
if (!newIndex.IsValid())
{
return Events::ProcessingResult::Failure;
}
Events::ProcessingResult transformAttributeResult;
SceneAttributeDataPopulatedContext dataPopulated(context, transformData, newIndex, nodeName);
transformAttributeResult = Events::Process(dataPopulated);
if (transformAttributeResult != Events::ProcessingResult::Failure)
{
transformAttributeResult = AddAttributeDataNodeWithContexts(dataPopulated);
}
return transformAttributeResult;
}
}
else
{
bool addedData = context.m_scene.GetGraph().SetContent(
context.m_currentGraphPosition,
transformData);
AZ_Assert(addedData, "Failed to add node data");
return addedData ? Events::ProcessingResult::Success : Events::ProcessingResult::Failure;
}
return Events::ProcessingResult::Ignored;
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,43 +0,0 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/Math/Transform.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
class FbxTransformImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(FbxTransformImporter, "{354EAAE2-DF31-4E11-BD8A-619419A3EA17}", SceneCore::LoadingComponent);
FbxTransformImporter();
~FbxTransformImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportTransform(SceneNodeAppendedContext& context);
protected:
static const char* s_transformNodeName;
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,164 +0,0 @@
/*
* 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 <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxUvMapImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxUVWrapper.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneData/GraphData/SkinMeshData.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexUVData.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
FbxUvMapImporter::FbxUvMapImporter()
{
BindToCall(&FbxUvMapImporter::ImportUvMaps);
}
void FbxUvMapImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxUvMapImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult FbxUvMapImporter::ImportUvMaps(SceneNodeAppendedContext& context)
{
AZ_TraceContext("Importer", "UV Map");
std::shared_ptr<FbxSDKWrapper::FbxMeshWrapper> fbxMesh =
context.m_sourceNode.GetMesh();
if (!fbxMesh)
{
return Events::ProcessingResult::Ignored;
}
Events::ProcessingResultCombiner combinedUvMapResults;
for (int uvElementIndex = 0; uvElementIndex < context.m_sourceNode.GetMesh()->GetElementUVCount(); ++uvElementIndex)
{
AZ_TraceContext("UV Map index", uvElementIndex);
FbxSDKWrapper::FbxUVWrapper fbxVertexUVs = fbxMesh->GetElementUV(uvElementIndex);
if (!fbxVertexUVs.IsValid())
{
AZ_TracePrintf(Utilities::WarningWindow, "Invalid UV Map found, ignoring");
continue;
}
AZStd::string nodeName = fbxVertexUVs.GetName();
RenamedNodesMap::SanitizeNodeName(nodeName, context.m_scene.GetGraph(), context.m_currentGraphPosition, "UV");
AZ_TraceContext("UV Map Name", nodeName);
AZStd::shared_ptr<DataTypes::IGraphObject> parentData =
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
AZ_Assert(parentData && parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()),
"Tried to construct uv stream attribute for invalid or non-mesh parent data");
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
{
combinedUvMapResults += Events::ProcessingResult::Failure;
continue;
}
const SceneData::GraphData::MeshData* const parentMeshData =
azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
size_t vertexCount = parentMeshData->GetVertexCount();
AZStd::shared_ptr<SceneData::GraphData::MeshVertexUVData> uvMap = BuildVertexUVData(fbxVertexUVs, vertexCount, fbxMesh);
AZ_Assert(uvMap, "Failed to allocate UV map data for scene graph.");
if (!uvMap)
{
combinedUvMapResults += Events::ProcessingResult::Failure;
continue;
}
Containers::SceneGraph::NodeIndex newIndex =
context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, nodeName.c_str());
AZ_Assert(newIndex.IsValid(), "Failed to create SceneGraph node for attribute.");
if (!newIndex.IsValid())
{
combinedUvMapResults += Events::ProcessingResult::Failure;
continue;
}
Events::ProcessingResult uvMapResults;
SceneAttributeDataPopulatedContext dataPopulated(context, uvMap, newIndex, nodeName);
uvMapResults = Events::Process(dataPopulated);
if (uvMapResults != Events::ProcessingResult::Failure)
{
uvMapResults = AddAttributeDataNodeWithContexts(dataPopulated);
}
combinedUvMapResults += uvMapResults;
}
return combinedUvMapResults.GetResult();
}
AZStd::shared_ptr<SceneData::GraphData::MeshVertexUVData> FbxUvMapImporter::BuildVertexUVData(const FbxSDKWrapper::FbxUVWrapper& uvs,
size_t vertexCount, const std::shared_ptr<FbxSDKWrapper::FbxMeshWrapper>& fbxMesh)
{
AZStd::shared_ptr<SceneData::GraphData::MeshVertexUVData> uvData = AZStd::make_shared<AZ::SceneData::GraphData::MeshVertexUVData>();
uvData->ReserveContainerSpace(vertexCount);
uvData->SetCustomName(uvs.GetName());
const int fbxPolygonCount = fbxMesh->GetPolygonCount();
const int* const fbxPolygonVertices = fbxMesh->GetPolygonVertices();
for (int fbxPolygonIndex = 0; fbxPolygonIndex < fbxPolygonCount; ++fbxPolygonIndex)
{
const int fbxPolygonVertexCount = fbxMesh->GetPolygonSize(fbxPolygonIndex);
if (fbxPolygonVertexCount <= 2)
{
continue;
}
const int fbxVertexStartIndex = fbxMesh->GetPolygonVertexIndex(fbxPolygonIndex);
for (int uvIndex = 0; uvIndex < fbxPolygonVertexCount; ++uvIndex)
{
const int fbxPolygonVertexIndex = fbxVertexStartIndex + uvIndex;
const int fbxControlPointIndex = fbxPolygonVertices[fbxPolygonVertexIndex];
Vector2 uv = uvs.GetElementAt(fbxPolygonIndex, fbxPolygonVertexIndex, fbxControlPointIndex);
uv.SetY(1.0f - uv.GetY());
uvData->AppendUV(uv);
}
}
if (uvData->GetCount() != vertexCount)
{
AZ_TracePrintf(Utilities::ErrorWindow, "Vertex count (%i) doesn't match the number of entries for the uv set %s (%i)",
vertexCount, uvs.GetName(), uvData->GetCount());
return nullptr;
}
return uvData;
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -1,58 +0,0 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace SceneData
{
namespace GraphData
{
class MeshVertexUVData;
}
}
namespace FbxSDKWrapper
{
class FbxMeshWrapper;
class FbxUVWrapper;
}
namespace SceneAPI
{
namespace FbxSceneBuilder
{
class FbxUvMapImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(FbxUvMapImporter, "{B16CD69D-3C0C-4FE2-B481-1084B1C36242}", SceneCore::LoadingComponent);
FbxUvMapImporter();
~FbxUvMapImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportUvMaps(SceneNodeAppendedContext& context);
protected:
AZStd::shared_ptr<SceneData::GraphData::MeshVertexUVData> BuildVertexUVData(const FbxSDKWrapper::FbxUVWrapper& uvs,
size_t vertexCount, const std::shared_ptr<FbxSDKWrapper::FbxMeshWrapper>& fbxMesh);
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -12,12 +12,8 @@
#include <AzCore/Math/Transform.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxSceneWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxTypeConverter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/ImporterUtilities.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Containers/Views/PairIterator.h>
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphDownwardsIterator.h>
@@ -50,19 +46,7 @@ namespace AZ
dataPopulated.m_scene.GetGraph().SetContent(dataPopulated.m_currentGraphPosition,
AZStd::move(dataPopulated.m_graphData));
if (azrtti_istypeof<SceneDataPopulatedContext>(dataPopulated))
{
SceneDataPopulatedContext* dataPopulatedContext = azrtti_cast<SceneDataPopulatedContext*>(&dataPopulated);
SceneNodeAppendedContext nodeAppended(*dataPopulatedContext, dataPopulated.m_currentGraphPosition);
nodeResults += Events::Process(nodeAppended);
SceneNodeAddedAttributesContext addedAttributes(nodeAppended);
nodeResults += Events::Process(addedAttributes);
SceneNodeFinalizeContext finalizeNode(addedAttributes);
nodeResults += Events::Process(finalizeNode);
}
else
if (azrtti_istypeof<AssImpSceneDataPopulatedContext>(dataPopulated))
{
AssImpSceneDataPopulatedContext* dataPopulatedContext = azrtti_cast<AssImpSceneDataPopulatedContext*>(&dataPopulated);
AssImpSceneNodeAppendedContext nodeAppended(*dataPopulatedContext, dataPopulated.m_currentGraphPosition);
@@ -91,13 +75,7 @@ namespace AZ
dataPopulated.m_scene.GetGraph().SetContent(dataPopulated.m_currentGraphPosition,
AZStd::move(dataPopulated.m_graphData));
if (azrtti_istypeof<SceneAttributeDataPopulatedContext>(dataPopulated))
{
SceneAttributeDataPopulatedContext* dataPopulatedContext = azrtti_cast<SceneAttributeDataPopulatedContext*>(&dataPopulated);
SceneAttributeNodeAppendedContext nodeAppended(*dataPopulatedContext, dataPopulated.m_currentGraphPosition);
nodeResults += Events::Process(nodeAppended);
}
else
if (azrtti_istypeof<AssImpSceneAttributeDataPopulatedContext>(dataPopulated))
{
AssImpSceneAttributeDataPopulatedContext* dataPopulatedContext = azrtti_cast<AssImpSceneAttributeDataPopulatedContext*>(&dataPopulated);
AssImpSceneAttributeNodeAppendedContext nodeAppended(*dataPopulatedContext, dataPopulated.m_currentGraphPosition);
@@ -456,48 +434,6 @@ namespace AZ
return true;
}
bool GetBindPoseLocalTransform(const FbxSDKWrapper::FbxSceneWrapper& sceneWrapper,
FbxSDKWrapper::FbxNodeWrapper& nodeWrapper, SceneAPI::DataTypes::MatrixType& xf)
{
PoseList poseList;
FbxArray<int> nodeIndices;
FbxNode* node = nodeWrapper.GetFbxNode();
FbxScene* scene = sceneWrapper.GetFbxScene();
FbxMatrix nodeMatrix;
if (FbxPose::GetBindPoseContaining(scene, node, poseList, nodeIndices))
{
nodeMatrix = poseList[0]->GetMatrix(nodeIndices[0]);
}
else
{
return false;
}
// We are after the local transform of the node while fbx bind pose provides the global transform.
// To get the local transform, we multiply with the inverse of the parent's global transform.
FbxNode* parentNode = node->GetParent();
FbxMatrix parentMatrix;
if (parentNode)
{
poseList.Clear();
nodeIndices.Clear();
if (FbxPose::GetBindPoseContaining(scene, parentNode, poseList, nodeIndices))
{
parentMatrix = poseList[0]->GetMatrix(nodeIndices[0]);
}
else
{
parentMatrix = parentNode->EvaluateGlobalTransform();
}
}
FbxMatrix nodeLocalMatrix = parentMatrix.Inverse() * nodeMatrix;
xf = FbxSDKWrapper::FbxTypeConverter::ToTransform(nodeLocalMatrix);
return true;
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -12,7 +12,9 @@
#pragma once
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/ImportContexts.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
#include <SceneAPI/SceneCore/DataTypes/MatrixType.h>
#include <SceneAPI/SceneCore/Events/CallProcessorBus.h>
@@ -20,12 +22,6 @@ namespace AZ
{
struct Uuid;
namespace FbxSDKWrapper
{
class FbxNodeWrapper;
class FbxSceneWrapper;
}
namespace SceneAPI
{
namespace FbxSceneBuilder
@@ -42,7 +38,6 @@ namespace AZ
const AZ::Uuid& uuid);
inline bool NodeHasAncestorOfType(const CoreSceneGraph& graph, CoreGraphNodeIndex nodeIndex,
const AZ::Uuid& uuid);
inline bool IsSkinnedMesh(const FbxSDKWrapper::FbxNodeWrapper& sourceNode);
CoreProcessingResult AddDataNodeWithContexts(SceneDataPopulatedContextBase& dataContext);
CoreProcessingResult AddAttributeDataNodeWithContexts(SceneAttributeDataPopulatedContextBase& dataContext);
bool AreSceneGraphsEqual(const CoreSceneGraph& lhsGraph, const CoreSceneGraph& rhsGraph);
@@ -51,12 +46,8 @@ namespace AZ
bool IsGraphDataEqual(const AZStd::shared_ptr<const DataTypes::IGraphObject>& lhs,
const AZStd::shared_ptr<const DataTypes::IGraphObject>& rhs);
// If the scene contains bindpose information for the node, returns true and sets "xf" to the local transform
// of the node in bindpose. Returns false if bindpose info is not available for the node.
bool GetBindPoseLocalTransform(const FbxSDKWrapper::FbxSceneWrapper& sceneWrapper,
FbxSDKWrapper::FbxNodeWrapper& nodeWrapper, DataTypes::MatrixType& xf);
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.inl>
#include <SceneAPI/FbxSceneBuilder/Importers/ImporterUtilities.inl>
@@ -10,10 +10,7 @@
*
*/
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxSkinWrapper.h>
#include <SceneAPI/FbxSceneBuilder/Importers/ImporterUtilities.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/DataTypes/IGraphObject.h>
@@ -57,12 +54,6 @@ namespace AZ
return false;
}
bool IsSkinnedMesh(const FbxSDKWrapper::FbxNodeWrapper& sourceNode)
{
const std::shared_ptr<FbxSDKWrapper::FbxMeshWrapper> fbxMesh = sourceNode.GetMesh();
return (fbxMesh && (fbxMesh->GetDeformerCount(FbxDeformer::eSkin) > 0 || fbxMesh->GetDeformerCount(FbxDeformer::eBlendShape) > 0));
}
bool AreScenesEqual(const CoreScene& lhs, const CoreScene& rhs)
{
if (lhs.GetGraph().GetNodeCount() != rhs.GetGraph().GetNodeCount())
@@ -1,312 +0,0 @@
/*
* 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 <AzCore/Casting/numeric_cast.h>
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/FbxMeshImporterUtilities.h>
#include <SceneAPI/FbxSDKWrapper/FbxMeshWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxBlendShapeWrapper.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneData/GraphData/BlendShapeData.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
bool BuildSceneMeshFromFbxMesh(const AZStd::shared_ptr<SceneData::GraphData::MeshData>& mesh,
const FbxSDKWrapper::FbxMeshWrapper& sourceMesh, const FbxSceneSystem& sceneSystem)
{
// Save unit sizes of the mesh
mesh->SetUnitSizeInMeters(sceneSystem.GetUnitSizeInMeters());
mesh->SetOriginalUnitSizeInMeters(sceneSystem.GetOriginalUnitSizeInMeters());
// Get mesh subset count by scanning material IDs in meshes.
// For negative material ids we will add an additional
// subset at the end, see "++maxMaterialIndex".
// These defines material index range for all polygons in the mesh
// Each polygon has a material index
int minMeshMaterialIndex = INT_MAX;
int maxMeshMaterialIndex = INT_MIN;
FbxLayerElementArrayTemplate<int>* fbxMaterialIndices;
sourceMesh.GetMaterialIndices(&fbxMaterialIndices); // per polygon
int fbxPolygonCount = sourceMesh.GetPolygonCount();
AZ_Error("FbxSceneBuilder", fbxPolygonCount,
"Source mesh %s polygon count is 0. Zero count meshes are not supported, either remove this mesh or add polygons to it.",
sourceMesh.GetName());
for (int fbxPolygonIndex = 0; fbxPolygonIndex < fbxPolygonCount; ++fbxPolygonIndex)
{
// if the polygon has less than 3 vertices, it's not a valid polygon and is skipped
const int fbxPolygonVertexCount = sourceMesh.GetPolygonSize(fbxPolygonIndex);
if (fbxPolygonVertexCount <= 2)
{
continue;
}
// Get the material index of each polygon
const int meshMaterialIndex = fbxMaterialIndices ? (*fbxMaterialIndices)[fbxPolygonIndex] : -1;
minMeshMaterialIndex = AZ::GetMin<int>(minMeshMaterialIndex, meshMaterialIndex);
maxMeshMaterialIndex = AZ::GetMax<int>(maxMeshMaterialIndex, meshMaterialIndex);
}
if (minMeshMaterialIndex > maxMeshMaterialIndex)
{
return false;
}
if (maxMeshMaterialIndex < 0)
{
minMeshMaterialIndex = maxMeshMaterialIndex = 0;
}
else if (minMeshMaterialIndex < 0)
{
minMeshMaterialIndex = 0;
++maxMeshMaterialIndex;
}
// Fill geometry
// Control points contain positions of vertices
AZStd::vector<Vector3> fbxControlPoints = sourceMesh.GetControlPoints();
const int* const fbxPolygonVertices = sourceMesh.GetPolygonVertices();
fbxMaterialIndices = nullptr;
sourceMesh.GetMaterialIndices(&fbxMaterialIndices); // per polygon
// Iterate through each polygon in the mesh and convert data
fbxPolygonCount = sourceMesh.GetPolygonCount();
for (int fbxPolygonIndex = 0; fbxPolygonIndex < fbxPolygonCount; ++fbxPolygonIndex)
{
const int fbxPolygonVertexCount = sourceMesh.GetPolygonSize(fbxPolygonIndex);
if (fbxPolygonVertexCount <= 2)
{
continue;
}
AZ_TraceContext("Polygon Index", fbxPolygonIndex);
// Ensure the validity of the material index for the polygon
int fbxMaterialIndex = fbxMaterialIndices ? (*fbxMaterialIndices)[fbxPolygonIndex] : -1;
if (fbxMaterialIndex < minMeshMaterialIndex || fbxMaterialIndex > maxMeshMaterialIndex)
{
fbxMaterialIndex = maxMeshMaterialIndex;
}
const int fbxVertexStartIndex = sourceMesh.GetPolygonVertexIndex(fbxPolygonIndex);
// Triangulate polygon as a fan and remember resulting vertices and faces
int firstMeshVertexIndex = -1;
int previousMeshVertexIndex = -1;
AZ::SceneAPI::DataTypes::IMeshData::Face meshFace;
int verticesInMeshFace = 0;
// Iterate through each vertex in the polygon
for (int vertexIndex = 0; vertexIndex < fbxPolygonVertexCount; ++vertexIndex)
{
const int meshVertexIndex = aznumeric_caster(mesh->GetVertexCount());
const int fbxPolygonVertexIndex = fbxVertexStartIndex + vertexIndex;
const int fbxControlPointIndex = fbxPolygonVertices[fbxPolygonVertexIndex];
Vector3 meshPosition = fbxControlPoints[fbxControlPointIndex];
Vector3 meshVertexNormal;
sourceMesh.GetPolygonVertexNormal(fbxPolygonIndex, vertexIndex, meshVertexNormal);
sceneSystem.SwapVec3ForUpAxis(meshPosition);
sceneSystem.ConvertUnit(meshPosition);
// Add position
mesh->AddPosition(meshPosition);
// Add normal
sceneSystem.SwapVec3ForUpAxis(meshVertexNormal);
meshVertexNormal.NormalizeSafe();
mesh->AddNormal(meshVertexNormal);
mesh->SetVertexIndexToControlPointIndexMap(meshVertexIndex, fbxControlPointIndex);
// Add face
{
if (vertexIndex == 0)
{
firstMeshVertexIndex = meshVertexIndex;
}
int meshVertices[3];
int meshVertexCount = 0;
meshVertices[meshVertexCount++] = meshVertexIndex;
// If we already have generated one triangle before, make a new triangle at a time as we encounter a new vertex.
// The new triangle is composed with the first vertex of the polygon, the last vertex, and the current vertex.
if (vertexIndex >= 3)
{
meshVertices[meshVertexCount++] = firstMeshVertexIndex;
meshVertices[meshVertexCount++] = previousMeshVertexIndex;
}
for (int faceVertexIndex = 0; faceVertexIndex < meshVertexCount; ++faceVertexIndex)
{
meshFace.vertexIndex[verticesInMeshFace++] = meshVertices[faceVertexIndex];
if (verticesInMeshFace == 3)
{
verticesInMeshFace = 0;
mesh->AddFace(meshFace, fbxMaterialIndex);
}
}
}
previousMeshVertexIndex = meshVertexIndex;
}
// Report problem if there are vertices that left for forming a polygon
if (verticesInMeshFace != 0)
{
AZ_TracePrintf(Utilities::ErrorWindow, "Internal error in mesh filler");
return false;
}
}
// Report problem if no vertex or face converted to MeshData
if (mesh->GetVertexCount() <= 0 || mesh->GetFaceCount() <= 0)
{
AZ_TracePrintf(Utilities::ErrorWindow, "Missing geometry data in mesh node");
return false;
}
return true;
}
// Currently doesn't maintain a list of unique control points.
// Normals are associated with each triangle vertex from the face.
bool BuildSceneBlendShapeFromFbxBlendShape(const AZStd::shared_ptr<SceneData::GraphData::BlendShapeData>& blendShape,
const AZStd::shared_ptr<const FbxSDKWrapper::FbxMeshWrapper>& sourceMesh, const FbxSceneSystem& sceneSystem)
{
// Control points contain positions of vertices
const AZStd::vector<Vector3>& fbxControlPoints = sourceMesh->GetControlPoints();
const int* const fbxPolygonVertices = sourceMesh->GetPolygonVertices();
// Iterate through each polygon in the mesh and convert data
const int fbxPolygonCount = sourceMesh->GetPolygonCount();
for (int fbxPolygonIndex = 0; fbxPolygonIndex < fbxPolygonCount; ++fbxPolygonIndex)
{
const int fbxPolygonVertexCount = sourceMesh->GetPolygonSize(fbxPolygonIndex);
if (fbxPolygonVertexCount <= 2)
{
continue;
}
AZ_TraceContext("Polygon Index", fbxPolygonIndex);
const int fbxVertexStartIndex = sourceMesh->GetPolygonVertexIndex(fbxPolygonIndex);
// Triangulate polygon as a fan and remember resulting vertices and faces
int firstMeshVertexIndex = -1;
int previousMeshVertexIndex = -1;
DataTypes::IBlendShapeData::Face face;
int verticesInMeshFace = 0;
// Iterate through each vertex in the polygon
for (int vertexIndex = 0; vertexIndex < fbxPolygonVertexCount; ++vertexIndex)
{
const int meshVertexIndex = aznumeric_caster(blendShape->GetVertexCount());
const int fbxPolygonVertexIndex = fbxVertexStartIndex + vertexIndex;
const int fbxControlPointIndex = fbxPolygonVertices[fbxPolygonVertexIndex];
// This data allows for mapping vertex data to original Control Point index.
blendShape->SetVertexIndexToControlPointIndexMap(meshVertexIndex, fbxControlPointIndex);
Vector3 meshVertexPosition = fbxControlPoints[fbxControlPointIndex];
Vector3 meshVertexNormal;
sourceMesh->GetPolygonVertexNormal(fbxPolygonIndex, vertexIndex, meshVertexNormal);
// position
sceneSystem.SwapVec3ForUpAxis(meshVertexPosition);
sceneSystem.ConvertUnit(meshVertexPosition);
// normal
sceneSystem.SwapVec3ForUpAxis(meshVertexNormal);
meshVertexNormal.Normalize();
blendShape->AddPosition(meshVertexPosition);
blendShape->AddNormal(meshVertexNormal);
// Add face
{
if (vertexIndex == 0)
{
firstMeshVertexIndex = meshVertexIndex;
}
int meshVertices[3];
int meshNormals[3];
int meshVertexCount = 0;
meshVertices[meshVertexCount] = meshVertexIndex;
meshNormals[meshVertexCount++] = meshVertexIndex;
// If we already have generated one triangle before, make a new triangle at a time as we encounter a new vertex.
// The new triangle is composed with the first vertex of the polygon, the last vertex, and the current vertex.
if (vertexIndex >= 3)
{
meshVertices[meshVertexCount++] = firstMeshVertexIndex;
meshVertices[meshVertexCount++] = previousMeshVertexIndex;
}
for (int faceVertexIndex = 0; faceVertexIndex < meshVertexCount; ++faceVertexIndex)
{
face.vertexIndex[verticesInMeshFace++] = meshVertices[faceVertexIndex];
if (verticesInMeshFace == 3)
{
verticesInMeshFace = 0;
blendShape->AddFace(face);
break;
}
}
}
previousMeshVertexIndex = meshVertexIndex;
}
// Report problem if there are vertices that left for forming a polygon
if (verticesInMeshFace != 0)
{
AZ_TracePrintf(Utilities::ErrorWindow, "Internal error in mesh filler. Vertices were left without forming polygon");
return false;
}
}
// Report problem if no vertex or face converted to MeshData
if (blendShape->GetVertexCount() <= 0 || blendShape->GetFaceCount() <= 0)
{
AZ_TracePrintf(Utilities::ErrorWindow, "Missing geometry data in blendshape node");
return false;
}
return true;
}
}
}
}
@@ -1,42 +0,0 @@
/*
* 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.
*
*/
#pragma once
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxMeshWrapper;
}
namespace SceneData
{
namespace GraphData
{
class MeshData;
class BlendShapeData;
}
}
namespace SceneAPI
{
class FbxSceneSystem;
namespace FbxSceneBuilder
{
bool BuildSceneMeshFromFbxMesh(const AZStd::shared_ptr<SceneData::GraphData::MeshData>& mesh,
const FbxSDKWrapper::FbxMeshWrapper& sourceMesh, const FbxSceneSystem& sceneSystem);
bool BuildSceneBlendShapeFromFbxBlendShape(const AZStd::shared_ptr<SceneData::GraphData::BlendShapeData>& blendShape,
const AZStd::shared_ptr<const FbxSDKWrapper::FbxMeshWrapper>& sourceMesh, const FbxSceneSystem& sceneSystem);
}
}
}
@@ -14,7 +14,6 @@
#include <AzCore/std/algorithm.h>
#include <AzCore/std/string/conversions.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
@@ -13,7 +13,7 @@
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzTest/AzTest.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/ImporterUtilities.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/DataTypes/IGraphObject.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
@@ -19,39 +19,8 @@ set(FILES
FbxSceneSystem.cpp
ImportContexts/ImportContexts.h
ImportContexts/ImportContexts.cpp
ImportContexts/FbxImportContexts.h
ImportContexts/FbxImportContexts.cpp
ImportContexts/AssImpImportContexts.h
ImportContexts/AssImpImportContexts.cpp
Importers/FbxAnimationImporter.h
Importers/FbxAnimationImporter.cpp
Importers/FbxBoneImporter.h
Importers/FbxBoneImporter.cpp
Importers/FbxBlendShapeImporter.h
Importers/FbxBlendShapeImporter.cpp
Importers/FbxColorStreamImporter.h
Importers/FbxColorStreamImporter.cpp
Importers/FbxTangentStreamImporter.h
Importers/FbxTangentStreamImporter.cpp
Importers/FbxBitangentStreamImporter.h
Importers/FbxBitangentStreamImporter.cpp
Importers/FbxImporterUtilities.h
Importers/FbxImporterUtilities.inl
Importers/FbxImporterUtilities.cpp
Importers/FbxMaterialImporter.h
Importers/FbxMaterialImporter.cpp
Importers/FbxMeshImporter.h
Importers/FbxMeshImporter.cpp
Importers/FbxSkinImporter.h
Importers/FbxSkinImporter.cpp
Importers/FbxSkinWeightsImporter.h
Importers/FbxSkinWeightsImporter.cpp
Importers/FbxTransformImporter.h
Importers/FbxTransformImporter.cpp
Importers/FbxUvMapImporter.h
Importers/FbxUvMapImporter.cpp
Importers/Utilities/FbxMeshImporterUtilities.h
Importers/Utilities/FbxMeshImporterUtilities.cpp
Importers/Utilities/AssImpMeshImporterUtilities.h
Importers/Utilities/AssImpMeshImporterUtilities.cpp
Importers/Utilities/RenamedNodesMap.h
@@ -84,4 +53,7 @@ set(FILES
Importers/AssImpUvMapImporter.cpp
Importers/AssImpAnimationImporter.h
Importers/AssImpAnimationImporter.cpp
Importers/ImporterUtilities.h
Importers/ImporterUtilities.cpp
Importers/ImporterUtilities.inl
)