Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
#
# 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.
#
add_subdirectory(FbxSceneBuilder)
add_subdirectory(FbxSDKWrapper)
add_subdirectory(SceneCore)
add_subdirectory(SceneData)
add_subdirectory(SceneUI)
@@ -0,0 +1,40 @@
#
# 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.
#
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
set(sdkwrapper_dir ${CMAKE_CURRENT_LIST_DIR}/../SDKWrapper)
set(sdkwrapper_pal_dir ${sdkwrapper_dir}/Platform/${PAL_PLATFORM_NAME})
if (NOT PAL_TRAIT_BUILD_HOST_TOOLS)
return()
endif()
ly_add_target(
NAME FbxSDKWrapper STATIC
NAMESPACE AZ
FILES_CMAKE
fbxsdkwrapper_files.cmake
${sdkwrapper_dir}/sdkwrapper_files.cmake
${sdkwrapper_pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
PLATFORM_INCLUDE_FILES
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
INCLUDE_DIRECTORIES
PUBLIC
.
../..
${sdkwrapper_dir}
BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
AZ::AzToolsFramework
PUBLIC
3rdParty::FbxSdk
)
@@ -0,0 +1,47 @@
/*
* 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/std/smart_ptr/make_shared.h>
#include "FbxAnimCurveNodeWrapper.h"
#include "FbxAnimCurveWrapper.h"
#include "fbxsdk.h"
namespace AZ
{
namespace FbxSDKWrapper
{
FbxAnimCurveNodeWrapper::FbxAnimCurveNodeWrapper(FbxAnimCurveNode* fbxAnimCurveNode)
: m_fbxAnimCurveNode(fbxAnimCurveNode)
{
}
const char* FbxAnimCurveNodeWrapper::GetName() const
{
return m_fbxAnimCurveNode->GetName();
}
int FbxAnimCurveNodeWrapper::GetChannelCount() const
{
return m_fbxAnimCurveNode->GetChannelsCount();
}
int FbxAnimCurveNodeWrapper::GetCurveCount(int channelID) const
{
return m_fbxAnimCurveNode->GetCurveCount(channelID);
}
AZStd::shared_ptr<const FbxAnimCurveWrapper> FbxAnimCurveNodeWrapper::GetCurveWrapper(int channelID, int index) const
{
return AZStd::make_shared<const FbxAnimCurveWrapper>(static_cast<FbxAnimCurve*>(m_fbxAnimCurveNode->GetCurve(channelID, index)));
}
}
}
@@ -0,0 +1,40 @@
#pragma once
/*
* 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 "fbxsdk.h"
#include "FbxTimeWrapper.h"
#include <AzCore/std/smart_ptr/shared_ptr.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxAnimCurveWrapper;
class FbxAnimCurveNodeWrapper
{
public:
FbxAnimCurveNodeWrapper(FbxAnimCurveNode* fbxAnimCurveNode);
~FbxAnimCurveNodeWrapper() = default;
const char* GetName() const;
int GetChannelCount() const;
int GetCurveCount(int channelID) const;
AZStd::shared_ptr<const FbxAnimCurveWrapper> GetCurveWrapper(int channelID, int index) const;
protected:
FbxAnimCurveNode* m_fbxAnimCurveNode;
};
}
}
@@ -0,0 +1,34 @@
/*
* 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/FbxSDKWrapper/FbxAnimCurveWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxAnimCurveWrapper::FbxAnimCurveWrapper(FbxAnimCurve* fbxAnimCurve)
: m_fbxAnimCurve(fbxAnimCurve)
{
}
const char* FbxAnimCurveWrapper::GetName() const
{
return m_fbxAnimCurve->GetName();
}
float FbxAnimCurveWrapper::Evaluate(FbxTimeWrapper& time) const
{
return m_fbxAnimCurve->Evaluate(time.m_fbxTime);
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,34 @@
/*
* 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/FbxSDKWrapper/FbxTimeWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxAnimCurveWrapper
{
public:
FbxAnimCurveWrapper(FbxAnimCurve* fbxAnimCurve);
~FbxAnimCurveWrapper() = default;
const char* GetName() const;
float Evaluate(FbxTimeWrapper& time) const;
protected:
FbxAnimCurve* m_fbxAnimCurve;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,49 @@
/*
* 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/std/smart_ptr/make_shared.h>
#include <AzCore/Casting/numeric_cast.h>
#include <SceneAPI/FbxSDKWrapper/FbxAnimLayerWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxAnimCurveNodeWrapper.h>
#include "fbxsdk.h"
namespace AZ
{
namespace FbxSDKWrapper
{
FbxAnimLayerWrapper::FbxAnimLayerWrapper(FbxAnimLayer* fbxAnimLayer)
: m_fbxAnimLayer(fbxAnimLayer)
{
}
const char* FbxAnimLayerWrapper::GetName() const
{
return m_fbxAnimLayer->GetName();
}
u32 FbxAnimLayerWrapper::GetCurveNodeCount() const
{
return static_cast<u32>(m_fbxAnimLayer->GetMemberCount());
}
FbxAnimLayer* FbxAnimLayerWrapper::GetFbxLayer() const
{
return m_fbxAnimLayer;
}
AZStd::shared_ptr<const FbxAnimCurveNodeWrapper> FbxAnimLayerWrapper::GetCurveNodeWrapper(u32 index) const
{
return AZStd::make_shared<const FbxAnimCurveNodeWrapper>(static_cast<FbxAnimCurveNode*>(m_fbxAnimLayer->GetMember(aznumeric_cast<int>(index))));
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,39 @@
/*
* 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 <AzCore/std/smart_ptr/shared_ptr.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxAnimCurveNodeWrapper;
class FbxAnimLayerWrapper
{
friend class FbxNodeWrapper;
public:
FbxAnimLayerWrapper(FbxAnimLayer* fbxAnimLayer);
~FbxAnimLayerWrapper() = default;
const char* GetName() const;
u32 GetCurveNodeCount() const ;
FbxAnimLayer* GetFbxLayer() const;
AZStd::shared_ptr<const FbxAnimCurveNodeWrapper> GetCurveNodeWrapper(u32 index) const;
protected:
FbxAnimLayer* m_fbxAnimLayer;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,55 @@
/*
* 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/Debug/Trace.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <SceneAPI/FbxSDKWrapper/FbxAnimStackWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxAnimLayerWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxTimeSpanWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxAnimStackWrapper::FbxAnimStackWrapper(FbxAnimStack* fbxAnimStack)
: m_fbxAnimStack(fbxAnimStack)
{
AZ_Assert(fbxAnimStack, "Invalid FbxAnimStack input to initialize FbxAnimStackWrapper");
}
FbxAnimStackWrapper::~FbxAnimStackWrapper()
{
m_fbxAnimStack = nullptr;
}
const char* FbxAnimStackWrapper::GetName() const
{
return m_fbxAnimStack->GetName();
}
int FbxAnimStackWrapper::GetAnimationLayerCount() const
{
return m_fbxAnimStack->GetMemberCount<FbxAnimLayer>();
}
const AZStd::shared_ptr<FbxAnimLayerWrapper> FbxAnimStackWrapper::GetAnimationLayerAt(int index) const
{
AZ_Assert(index < GetAnimationLayerCount(), "Invalid animation layer index %d for layer count %d", index, GetAnimationLayerCount());
return AZStd::make_shared<FbxAnimLayerWrapper>(m_fbxAnimStack->GetMember<FbxAnimLayer>(index));
}
FbxTimeSpanWrapper FbxAnimStackWrapper::GetLocalTimeSpan() const
{
return FbxTimeSpanWrapper(m_fbxAnimStack->GetLocalTimeSpan());
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,42 @@
/*
* 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 <fbxsdk.h>
namespace AZ
{
namespace FbxSDKWrapper
{
using FbxSDKLongLong = FbxLongLong;
class FbxAnimLayerWrapper;
class FbxTimeSpanWrapper;
class FbxAnimStackWrapper
{
public:
FbxAnimStackWrapper(FbxAnimStack* fbxAnimStack);
virtual ~FbxAnimStackWrapper();
virtual const char* GetName() const;
virtual int GetAnimationLayerCount() const;
virtual const AZStd::shared_ptr<FbxAnimLayerWrapper> GetAnimationLayerAt(int index) const;
virtual FbxTimeSpanWrapper GetLocalTimeSpan() const;
protected:
FbxAnimStackWrapper() = default;
FbxAnimStack* m_fbxAnimStack;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,75 @@
/*
* 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/Debug/Trace.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/FbxSDKWrapper/FbxAxisSystemWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxTypeConverter.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxAxisSystemWrapper::FbxAxisSystemWrapper(const FbxAxisSystem& fbxAxisSystem)
: m_fbxAxisSystem(fbxAxisSystem)
{
}
FbxAxisSystemWrapper::UpVector FbxAxisSystemWrapper::GetUpVector(int& sign) const
{
switch (m_fbxAxisSystem.GetUpVector(sign))
{
case FbxAxisSystem::eXAxis:
return X;
case FbxAxisSystem::eYAxis:
return Y;
case FbxAxisSystem::eZAxis:
return Z;
default:
AZ_TraceContext("Unknown value", m_fbxAxisSystem.GetUpVector(sign));
AZ_TracePrintf(SceneAPI::Utilities::WarningWindow, "Unrecognized axis up vector type");
return Unknown;
}
}
SceneAPI::DataTypes::MatrixType FbxAxisSystemWrapper::CalculateConversionTransform(UpVector targetUpAxis)
{
FbxAxisSystem targetSystem;
switch (targetUpAxis)
{
case Y:
// Maya YUp coordinate system (UpVector = +Y, FrontVector = +Z, CoordSystem = +X (RightHanded))
targetSystem = FbxAxisSystem::MayaYUp;
break;
case Z:
// CryTek ZUp coordinate system (UpVector = +Z, FrontVector = +Y, CoordSystem = -X (RightHanded))
targetSystem = FbxAxisSystem(FbxAxisSystem::eZAxis, FbxAxisSystem::eParityOdd, FbxAxisSystem::eRightHanded);
break;
case X:
// Default XUp coordinate system (UpVector = +X, FrontVector = +Z, CoordSystem = -Y (RightHanded))
targetSystem = FbxAxisSystem(FbxAxisSystem::eXAxis, FbxAxisSystem::eParityOdd, FbxAxisSystem::eRightHanded);
break;
default:
AZ_TraceContext("Unknown value", targetUpAxis);
AZ_TracePrintf(SceneAPI::Utilities::WarningWindow, "Unrecognized axis conversion target axis type");
return SceneAPI::DataTypes::MatrixType::CreateIdentity();
}
FbxAMatrix targetMatrix;
targetSystem.GetMatrix(targetMatrix);
FbxAMatrix currentMatrix;
m_fbxAxisSystem.GetMatrix(currentMatrix);
FbxAMatrix adjustMatrix = targetMatrix * currentMatrix.Inverse();
return FbxTypeConverter::ToTransform(adjustMatrix);
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,44 @@
/*
* 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/SceneCore/DataTypes/MatrixType.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxAxisSystemWrapper
{
public:
enum UpVector
{
X,
Y,
Z,
Unknown
};
FbxAxisSystemWrapper() = default;
FbxAxisSystemWrapper(const FbxAxisSystem& fbxAxisSystem);
virtual ~FbxAxisSystemWrapper() = default;
virtual UpVector GetUpVector(int& sign) const;
virtual SceneAPI::DataTypes::MatrixType CalculateConversionTransform(UpVector targetUpAxis);
protected:
FbxAxisSystem m_fbxAxisSystem;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,100 @@
/*
* 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/std/smart_ptr/make_shared.h>
#include <AzCore/Debug/Trace.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/FbxSDKWrapper/FbxBlendShapeChannelWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxBlendShapeChannelWrapper::FbxBlendShapeChannelWrapper(FbxBlendShapeChannel* fbxBlendShapeChannel)
: m_fbxBlendShapeChannel(fbxBlendShapeChannel)
{
AZ_Assert(fbxBlendShapeChannel, "Invalid FbxSkin input to initialize FbxBlendShapeChannelWrapper");
}
FbxBlendShapeChannelWrapper::~FbxBlendShapeChannelWrapper()
{
m_fbxBlendShapeChannel = nullptr;
}
const char* FbxBlendShapeChannelWrapper::GetName() const
{
return m_fbxBlendShapeChannel->GetName();
}
//The engine currently only supports one target shape. If there are more than one,
//code will ultimately end up just using the max index returned by this function.
int FbxBlendShapeChannelWrapper::GetTargetShapeCount() const
{
return m_fbxBlendShapeChannel->GetTargetShapeCount();
}
//While not strictly true that the target shapes are meshes, for the purposes of the engine's
//current runtime they must be meshes.
AZStd::shared_ptr<const FbxMeshWrapper> FbxBlendShapeChannelWrapper::GetTargetShape(int index) const
{
//we need to create a duplicate FbxMesh from the base mesh and the target data
//FbxMeshWrapper needs an FbxMesh to point to so we are generating one
//by cloning the mesh data and then replacing with the morph data.
FbxShape* fbxShape = m_fbxBlendShapeChannel->GetTargetShape(index);
if (!fbxShape)
{
return nullptr;
}
FbxGeometry* fbxGeom = fbxShape->GetBaseGeometry();
if (fbxGeom && fbxGeom->GetAttributeType() == FbxNodeAttribute::EType::eMesh)
{
FbxMesh* fbxMesh = static_cast<FbxMesh*>(fbxGeom);
FbxMesh* fbxBlendMesh = FbxMesh::Create(m_fbxBlendShapeChannel->GetScene(),"");
fbxBlendMesh->Copy(*fbxMesh);
//TODO: test that mesh is managed by the sdk
const int count = fbxBlendMesh->GetControlPointsCount();
//set control points from blend shape
for (int i = 0; i < count; i++)
{
fbxBlendMesh->SetControlPointAt(fbxShape->GetControlPointAt(i), i);
}
//source data
FbxLayerElementArrayTemplate<FbxVector4>* normalsTemplate;
if (fbxShape->GetNormals(&normalsTemplate))
{
int normalCount = normalsTemplate->GetCount();
//destination data
FbxLayer* normalLayer = fbxBlendMesh->GetLayer(0, FbxLayerElement::eNormal);
if (normalLayer)
{
FbxLayerElementNormal* normals = normalLayer->GetNormals();
if (normals)
{
//set normal data from blend shape
for (int j = 0; j < normalCount; j++)
{
FbxVector4 normal = normalsTemplate->GetAt(j);
normals->GetDirectArray().SetAt(j, normal);
}
}
}
}
return AZStd::make_shared<FbxMeshWrapper>(fbxBlendMesh);
}
return nullptr;
}
}
}
@@ -0,0 +1,43 @@
/*
* 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 <AzCore/std/smart_ptr/shared_ptr.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxNodeWrapper;
class FbxMeshWrapper;
class FbxBlendShapeChannelWrapper
{
public:
FbxBlendShapeChannelWrapper(FbxBlendShapeChannel* fbxBlendShapeChannel);
virtual ~FbxBlendShapeChannelWrapper();
virtual const char* GetName() const;
virtual int GetTargetShapeCount() const;
//While not strictly true that the target shapes are meshes, for the purposes of the engine's
//current runtime they must be meshes.
virtual AZStd::shared_ptr<const FbxMeshWrapper> GetTargetShape(int index) const;
protected:
FbxBlendShapeChannelWrapper() = default;
FbxBlendShapeChannel* m_fbxBlendShapeChannel;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,74 @@
/*
* 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/Debug/Trace.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/FbxSDKWrapper/FbxMeshWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxBlendShapeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxBlendShapeChannelWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxBlendShapeWrapper::FbxBlendShapeWrapper(FbxBlendShape* fbxBlendShape)
: m_fbxBlendShape(fbxBlendShape)
{
AZ_Assert(fbxBlendShape, "Invalid FbxBlendShape input to initialize FbxBlendShapeWrapper");
}
FbxBlendShapeWrapper::~FbxBlendShapeWrapper()
{
m_fbxBlendShape = nullptr;
}
const char* FbxBlendShapeWrapper::GetName() const
{
return m_fbxBlendShape->GetName();
}
//Technically Fbx returns a FbxGeometry off this interface, but we only support meshes in the engine runtime.
AZStd::shared_ptr<const FbxMeshWrapper> FbxBlendShapeWrapper::GetGeometry() const
{
FbxGeometry* fbxGeom = m_fbxBlendShape->GetGeometry();
if (fbxGeom && fbxGeom->GetAttributeType() == FbxNodeAttribute::EType::eMesh )
{
return AZStd::make_shared<FbxMeshWrapper>(static_cast<FbxMesh*>(fbxGeom));
}
else
{
return nullptr;
}
}
int FbxBlendShapeWrapper::GetBlendShapeChannelCount() const
{
return m_fbxBlendShape->GetBlendShapeChannelCount();
}
AZStd::shared_ptr<const FbxBlendShapeChannelWrapper> FbxBlendShapeWrapper::GetBlendShapeChannel(int index) const
{
FbxBlendShapeChannel* fbxBlendShapeChannel = m_fbxBlendShape->GetBlendShapeChannel(index);
if (fbxBlendShapeChannel)
{
return AZStd::make_shared<FbxBlendShapeChannelWrapper>(fbxBlendShapeChannel);
}
else
{
return nullptr;
}
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,43 @@
/*
* 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 <AzCore/std/smart_ptr/shared_ptr.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxBlendShapeChannelWrapper;
class FbxNodeWrapper;
class FbxMeshWrapper;
class FbxBlendShapeWrapper
{
public:
FbxBlendShapeWrapper(FbxBlendShape* fbxBlendShape);
virtual ~FbxBlendShapeWrapper();
virtual const char* GetName() const;
//Technically Fbx returns a FbxGeometry off this interface, but we only support meshes in the engine runtime.
virtual AZStd::shared_ptr<const FbxMeshWrapper> GetGeometry() const;
virtual int GetBlendShapeChannelCount() const;
virtual AZStd::shared_ptr<const FbxBlendShapeChannelWrapper> GetBlendShapeChannel(int index) const;
protected:
FbxBlendShapeWrapper() = default;
FbxBlendShape* m_fbxBlendShape;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,31 @@
/*
* 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>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxLayerElementUtilities
{
public:
template <typename ValueType, typename ElementArrayType>
static void GetGeometryElement(ValueType& value, const ElementArrayType* elementArray,
int polygonIndex, int polygonVertexIndex, int controlPointIndex);
};
} // namespace FbxSDKWrapper
} // namespace AZ
#include "FbxLayerElementUtilities.inl"
@@ -0,0 +1,74 @@
/*
* 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/Debug/Trace.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
namespace AZ
{
namespace FbxSDKWrapper
{
template <typename ValueType, typename ElementArrayType>
void FbxLayerElementUtilities::GetGeometryElement( ValueType& value, const ElementArrayType* elementArray,
int polygonIndex, int polygonVertexIndex, int controlPointIndex)
{
if (!elementArray)
{
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Invalid ElementArrayType input");
return;
}
int fbxElementIndex;
switch (elementArray->GetMappingMode())
{
case FbxGeometryElement::eByControlPoint:
// One mapping coordinate for each surface control point/vertex.
fbxElementIndex = controlPointIndex;
break;
case FbxGeometryElement::eByPolygonVertex:
// One mapping coordinate for each vertex, for every polygon of which it is a part.
// This means that a vertex will have as many mapping coordinates as polygons of which it is a part.
fbxElementIndex = polygonVertexIndex;
break;
case FbxGeometryElement::eByPolygon:
// One mapping coordinate for the whole polygon.
fbxElementIndex = polygonIndex;
break;
default:
AZ_TraceContext("Unknown value", elementArray->GetMappingMode());
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Invalid ElementArrayType mapping mode");
return;
}
if (elementArray->GetReferenceMode() == FbxGeometryElement::eIndexToDirect)
{
// Convert index from "index of value's index" to "index of value".
const FbxLayerElementArrayTemplate<int>& indices = elementArray->GetIndexArray();
AZ_Assert(fbxElementIndex < indices.GetCount(), "Invalid element index %d", fbxElementIndex);
if (fbxElementIndex >= indices.GetCount())
{
return;
}
fbxElementIndex = indices.GetAt(fbxElementIndex);
}
const FbxLayerElementArrayTemplate<ValueType>& elements = elementArray->GetDirectArray();
AZ_Assert(fbxElementIndex < elements.GetCount(), "Invalid element index %d", fbxElementIndex);
if (fbxElementIndex >= elements.GetCount())
{
return;
}
value = elements.GetAt(fbxElementIndex);
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,185 @@
/*
* 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 <AzCore/Debug/Trace.h>
#include <AzCore/Math/MathUtils.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/FbxSDKWrapper/FbxMaterialWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxPropertyWrapper.h>
namespace
{
const char* s_physicalisedAttributeName = "physicalize";
const char* s_proxyNoDraw = "ProxyNoDraw";
}
namespace AZ
{
namespace FbxSDKWrapper
{
FbxMaterialWrapper::FbxMaterialWrapper(FbxSurfaceMaterial* fbxMaterial)
: SDKMaterial::MaterialWrapper(fbxMaterial)
{
AZ_Assert(fbxMaterial, "Invalid FbxSurfaceMaterial input to initialize FbxMaterialWrapper");
}
AZStd::string FbxMaterialWrapper::GetName() const
{
return m_fbxMaterial->GetInitialName();
}
AZ::Vector3 FbxMaterialWrapper::GetDiffuseColor() const
{
if (m_fbxMaterial->GetClassId().Is(FbxSurfaceLambert::ClassId))
{
FbxSurfaceLambert* lambertMat = static_cast<FbxSurfaceLambert*>(m_fbxMaterial);
const FbxDouble3 fbxValue = lambertMat->Diffuse.Get();
const float power = static_cast<float>(lambertMat->DiffuseFactor.Get());
return power * AZ::Vector3(static_cast<float>(fbxValue[0]), static_cast<float>(fbxValue[1]), static_cast<float>(fbxValue[2]));
}
else if (m_fbxMaterial->GetClassId().Is(FbxSurfacePhong::ClassId))
{
FbxSurfacePhong* phongMat = static_cast<FbxSurfacePhong*>(m_fbxMaterial);
const FbxDouble3 fbxValue = phongMat->Diffuse.Get();
const float power = static_cast<float>(phongMat->DiffuseFactor.Get());
return power * AZ::Vector3(static_cast<float>(fbxValue[0]), static_cast<float>(fbxValue[1]), static_cast<float>(fbxValue[2]));
}
return AZ::Vector3::CreateOne();
}
AZ::Vector3 FbxMaterialWrapper::GetSpecularColor() const
{
if (m_fbxMaterial->GetClassId().Is(FbxSurfacePhong::ClassId))
{
FbxSurfacePhong* phongMat = static_cast<FbxSurfacePhong*>(m_fbxMaterial);
const FbxDouble3 fbxValue = phongMat->Specular.Get();
const float power = static_cast<float>(phongMat->SpecularFactor.Get());
return power * AZ::Vector3(static_cast<float>(fbxValue[0]), static_cast<float>(fbxValue[1]), static_cast<float>(fbxValue[2]));
}
return AZ::Vector3::CreateZero();
}
AZ::Vector3 FbxMaterialWrapper::GetEmissiveColor() const
{
if (m_fbxMaterial->GetClassId().Is(FbxSurfaceLambert::ClassId))
{
FbxSurfaceLambert* lambertMat = static_cast<FbxSurfaceLambert*>(m_fbxMaterial);
const FbxDouble3 fbxValue = lambertMat->Emissive.Get();
const float power = static_cast<float>(lambertMat->EmissiveFactor.Get());
return power * AZ::Vector3(static_cast<float>(fbxValue[0]), static_cast<float>(fbxValue[1]), static_cast<float>(fbxValue[2]));
}
else if (m_fbxMaterial->GetClassId().Is(FbxSurfacePhong::ClassId))
{
FbxSurfacePhong* phongMat = static_cast<FbxSurfacePhong*>(m_fbxMaterial);
const FbxDouble3 fbxValue = phongMat->Emissive.Get();
const float power = static_cast<float>(phongMat->EmissiveFactor.Get());
return power * AZ::Vector3(static_cast<float>(fbxValue[0]), static_cast<float>(fbxValue[1]), static_cast<float>(fbxValue[2]));
}
return AZ::Vector3::CreateZero();
}
float FbxMaterialWrapper::GetShininess() const
{
if (m_fbxMaterial->GetClassId().Is(FbxSurfacePhong::ClassId))
{
FbxSurfacePhong* phongMat = static_cast<FbxSurfacePhong*>(m_fbxMaterial);
return static_cast<float>(phongMat->Shininess.Get());
}
return 10.f;
}
uint64_t FbxMaterialWrapper::GetUniqueId() const
{
return m_fbxMaterial->GetUniqueID();
}
float FbxMaterialWrapper::GetOpacity() const
{
// FBX materials are erroneously reporting a TransparencyFactor of 1.0 (fully transparent)
// even for values that are 0.0 in Maya. It is instead storing it in the components
// for TransparentColor, so extract from there instead.
if (m_fbxMaterial->GetClassId().Is(FbxSurfaceLambert::ClassId))
{
FbxSurfaceLambert* lambertMat = static_cast<FbxSurfaceLambert*>(m_fbxMaterial);
const FbxDouble3 fbxValue = lambertMat->TransparentColor.Get();
return 1.f - AZ::GetMin<float>(AZ::GetMin<float>(static_cast<float>(fbxValue[0]), static_cast<float>(fbxValue[1])), static_cast<float>(fbxValue[2]));
}
else if (m_fbxMaterial->GetClassId().Is(FbxSurfacePhong::ClassId))
{
FbxSurfacePhong* phongMat = static_cast<FbxSurfacePhong*>(m_fbxMaterial);
const FbxDouble3 fbxValue = phongMat->TransparentColor.Get();
return 1.f - AZ::GetMin<float>(AZ::GetMin<float>(static_cast<float>(fbxValue[0]), static_cast<float>(fbxValue[1])), static_cast<float>(fbxValue[2]));
}
return 1.f;
}
AZStd::string FbxMaterialWrapper::GetTextureFileName(const char* textureType) const
{
FbxFileTexture* fileTexture = nullptr;
FbxProperty property = m_fbxMaterial->FindProperty(textureType);
FbxDataType propertyType = property.GetPropertyDataType();
/// Engine currently doesn't support multiple textures. Right now we only use first texture of first layer.
int layeredTextureCount = property.GetSrcObjectCount<FbxLayeredTexture>();
if (layeredTextureCount > 0)
{
FbxLayeredTexture* layeredTexture = FbxCast<FbxLayeredTexture>(property.GetSrcObject<FbxLayeredTexture>(0));
int textureCount = layeredTexture->GetSrcObjectCount<FbxTexture>();
if (textureCount > 0)
{
fileTexture = FbxCast<FbxFileTexture>(layeredTexture->GetSrcObject<FbxTexture>(0));
}
}
else
{
int textureCount = property.GetSrcObjectCount<FbxTexture>();
if (textureCount > 0)
{
fileTexture = FbxCast<FbxFileTexture>(property.GetSrcObject<FbxTexture>(0));
}
}
return fileTexture ? fileTexture->GetFileName() : AZStd::string();
}
AZStd::string FbxMaterialWrapper::GetTextureFileName(const AZStd::string& textureType) const
{
return GetTextureFileName(textureType.c_str());
}
AZStd::string FbxMaterialWrapper::GetTextureFileName(MaterialMapType textureType) const
{
switch (textureType)
{
case MaterialMapType::Diffuse:
return GetTextureFileName(FbxSurfaceMaterial::sDiffuse);
case MaterialMapType::Specular:
return GetTextureFileName(FbxSurfaceMaterial::sSpecular);
case MaterialMapType::Bump:
return GetTextureFileName(FbxSurfaceMaterial::sBump);
case MaterialMapType::Normal:
return GetTextureFileName(FbxSurfaceMaterial::sNormalMap);
default:
AZ_TraceContext("Unknown value", aznumeric_cast<int>(textureType));
AZ_TracePrintf(SceneAPI::Utilities::WarningWindow, "Unrecognized MaterialMapType retrieved");
return AZStd::string();
}
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,44 @@
/*
* 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 <AzCore/std/string/string.h>
#include <SceneAPI/SDKWrapper/MaterialWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxMaterialWrapper : public SDKMaterial::MaterialWrapper
{
public:
AZ_RTTI(FbxMaterialWrapper, "{227582F6-93BC-4E44-823E-FB1D631443A7}", SDKMaterial::MaterialWrapper);
FbxMaterialWrapper(FbxSurfaceMaterial* fbxMaterial);
~FbxMaterialWrapper() override = default;
AZStd::string GetName() const override;
virtual AZStd::string GetTextureFileName(const char* textureType) const;
virtual AZStd::string GetTextureFileName(const AZStd::string& textureType) const;
AZStd::string GetTextureFileName(MaterialMapType textureType) const override;
AZ::Vector3 GetDiffuseColor() const override;
AZ::Vector3 GetSpecularColor() const override;
AZ::Vector3 GetEmissiveColor() const override;
float GetOpacity() const override;
float GetShininess() const override;
uint64_t GetUniqueId() const override;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,156 @@
/*
* 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 <AzCore/std/smart_ptr/make_shared.h>
#include <SceneAPI/FbxSDKWrapper/FbxMeshWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxSkinWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxVertexTangentWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxVertexBitangentWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxBlendShapeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxTypeConverter.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxMeshWrapper::FbxMeshWrapper(FbxMesh* fbxMesh)
: m_fbxMesh(fbxMesh)
{
AZ_Assert(fbxMesh, "Invalid FbxMesh input to initialize FbxMeshWrapper");
}
FbxMeshWrapper::~FbxMeshWrapper()
{
m_fbxMesh = nullptr;
}
const char* FbxMeshWrapper::GetName() const
{
return m_fbxMesh->GetName();
}
int FbxMeshWrapper::GetDeformerCount() const
{
return m_fbxMesh->GetDeformerCount();
}
int FbxMeshWrapper::GetDeformerCount(int type) const
{
return m_fbxMesh->GetDeformerCount(static_cast<FbxDeformer::EDeformerType>(type));
}
int FbxMeshWrapper::GetControlPointsCount() const
{
return m_fbxMesh->GetControlPointsCount();
}
AZStd::vector<Vector3> FbxMeshWrapper::GetControlPoints() const
{
FbxVector4* controlPoints = m_fbxMesh->GetControlPoints();
AZStd::vector<Vector3> azControlPoints;
azControlPoints.reserve(aznumeric_caster(GetControlPointsCount()));
for (int i = 0; i < GetControlPointsCount(); ++i)
{
azControlPoints.push_back(FbxTypeConverter::ToVector3(controlPoints[i]));
}
return azControlPoints;
}
AZStd::shared_ptr<const FbxSkinWrapper> FbxMeshWrapper::GetSkin(int index) const
{
FbxSkin* skin = static_cast<FbxSkin*>(m_fbxMesh->GetDeformer(index, FbxDeformer::eSkin));
return skin ? AZStd::make_shared<const FbxSkinWrapper>(skin) : nullptr;
}
AZStd::shared_ptr<const FbxBlendShapeWrapper> FbxMeshWrapper::GetBlendShape(int index) const
{
int deformerCount = m_fbxMesh->GetDeformerCount();
int blendshapeCount = m_fbxMesh->GetDeformerCount(FbxDeformer::eBlendShape);
FbxBlendShape* blendShape = static_cast<FbxBlendShape*>(m_fbxMesh->GetDeformer(index, FbxDeformer::eBlendShape));
return blendShape ? AZStd::make_shared<const FbxBlendShapeWrapper>(blendShape) : nullptr;
}
int FbxMeshWrapper::GetPolygonCount() const
{
return m_fbxMesh->GetPolygonCount();
}
int FbxMeshWrapper::GetPolygonSize(int polygonIndex) const
{
return m_fbxMesh->GetPolygonSize(polygonIndex);
}
int* FbxMeshWrapper::GetPolygonVertices() const
{
return m_fbxMesh->GetPolygonVertices();
}
int FbxMeshWrapper::GetPolygonVertexIndex(int polygonIndex) const
{
return m_fbxMesh->GetPolygonVertexIndex(polygonIndex);
}
bool FbxMeshWrapper::GetMaterialIndices(FbxLayerElementArrayTemplate<int>** lockableArray) const
{
return m_fbxMesh->GetMaterialIndices(lockableArray);
}
FbxUVWrapper FbxMeshWrapper::GetElementUV(int index)
{
return FbxUVWrapper(m_fbxMesh->GetElementUV(index));
}
FbxVertexTangentWrapper FbxMeshWrapper::GetElementTangent(int index)
{
return FbxVertexTangentWrapper(m_fbxMesh->GetElementTangent(index));
}
FbxVertexBitangentWrapper FbxMeshWrapper::GetElementBitangent(int index)
{
return FbxVertexBitangentWrapper(m_fbxMesh->GetElementBinormal(index));
}
int FbxMeshWrapper::GetElementUVCount() const
{
return m_fbxMesh->GetElementUVCount();
}
int FbxMeshWrapper::GetElementTangentCount() const
{
return m_fbxMesh->GetElementTangentCount();
}
int FbxMeshWrapper::GetElementBitangentCount() const
{
return m_fbxMesh->GetElementBinormalCount();
}
FbxVertexColorWrapper FbxMeshWrapper::GetElementVertexColor(int index)
{
return FbxVertexColorWrapper(m_fbxMesh->GetElementVertexColor(index));
}
int FbxMeshWrapper::GetElementVertexColorCount() const
{
return m_fbxMesh->GetElementVertexColorCount();
}
bool FbxMeshWrapper::GetPolygonVertexNormal(int polyIndex, int vertexIndex, Vector3& normal) const
{
FbxVector4 fbxNormal;
bool hasVertexNormal = m_fbxMesh->GetPolygonVertexNormal(polyIndex, vertexIndex, fbxNormal);
normal = FbxTypeConverter::ToVector3(fbxNormal);
return hasVertexNormal;
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,89 @@
/*
* 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 <AzCore/Math/Vector3.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <SceneAPI/FbxSDKWrapper/FbxVertexColorWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxUVWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxSkinWrapper;
class FbxBlendShapeWrapper;
class FbxVertexTangentWrapper;
class FbxVertexBitangentWrapper;
class FbxMeshWrapper
{
public:
FbxMeshWrapper(FbxMesh* fbxMesh);
virtual ~FbxMeshWrapper();
virtual const char* GetName() const;
virtual int GetDeformerCount() const;
virtual int GetDeformerCount(int type) const;
virtual AZStd::shared_ptr<const FbxSkinWrapper> GetSkin(int index) const;
virtual AZStd::shared_ptr<const FbxBlendShapeWrapper> GetBlendShape(int index) const;
virtual bool GetMaterialIndices(FbxLayerElementArrayTemplate<int>** lockableArray) const;
// Vertex positions access
// Get the control points number
virtual int GetControlPointsCount() const;
// Get the array of control points
virtual AZStd::vector<Vector3> GetControlPoints() const;
// Polygon data accesses
// Get the polygon count of this mesh
virtual int GetPolygonCount() const;
// Get the number of polygon vertices in a polygon
virtual int GetPolygonSize(int polygonIndex) const;
// Get the array of polygon vertices (i.e: indices to the control points)
virtual int* GetPolygonVertices() const;
// Gets the start index into the array returned by GetPolygonVertices() for the given polygon
virtual int GetPolygonVertexIndex(int polygonIndex) const;
// Vertex colors and UV textures accesses
// Returns this geometry's UV element
virtual FbxUVWrapper GetElementUV(int index = 0);
virtual int GetElementUVCount() const;
virtual int GetElementTangentCount() const;
virtual int GetElementBitangentCount() const;
virtual FbxVertexTangentWrapper GetElementTangent(int index = 0);
virtual FbxVertexBitangentWrapper GetElementBitangent(int index = 0);
// Returns this geometry's vertex color element
virtual FbxVertexColorWrapper GetElementVertexColor(int index = 0);
virtual int GetElementVertexColorCount() const;
// Get the normal associated with the specified polygon vertex
virtual bool GetPolygonVertexNormal(int polyIndex, int vertexIndex, Vector3& normal) const;
protected:
FbxMeshWrapper() = default;
FbxMesh* m_fbxMesh;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,220 @@
/*
* 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/std/smart_ptr/make_shared.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxMaterialWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxTypeConverter.h>
#include <SceneAPI/FbxSDKWrapper/FbxAnimLayerWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxAnimCurveWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxNodeWrapper::FbxNodeWrapper(FbxNode* fbxNode)
: NodeWrapper(fbxNode)
{
AZ_Assert(fbxNode, "Invalid FbxNode to initialize FbxNodeWrapper");
}
FbxNodeWrapper::~FbxNodeWrapper()
{
}
int FbxNodeWrapper::GetMaterialCount() const
{
return m_fbxNode->GetMaterialCount();
}
const char* FbxNodeWrapper::GetMaterialName(int index) const
{
if (index < GetMaterialCount())
{
return m_fbxNode->GetMaterial(index)->GetName();
}
AZ_Assert(index < GetMaterialCount(), "Invalid material index %d", index);
return nullptr;
}
const std::shared_ptr<FbxMeshWrapper> FbxNodeWrapper::GetMesh() const
{
FbxMesh* mesh = m_fbxNode->GetMesh();
return mesh ? std::shared_ptr<FbxMeshWrapper>(new FbxMeshWrapper(mesh)) : nullptr;
}
const std::shared_ptr<FbxPropertyWrapper> FbxNodeWrapper::FindProperty(const char* name) const
{
FbxProperty propertyName = m_fbxNode->FindProperty(name);
return std::shared_ptr<FbxPropertyWrapper>(new FbxPropertyWrapper(&propertyName));
}
bool FbxNodeWrapper::IsBone() const
{
return (m_fbxNode->GetSkeleton() != nullptr);
}
bool FbxNodeWrapper::IsMesh() const
{
return (m_fbxNode->GetMesh() != nullptr);
}
const char* FbxNodeWrapper::GetName() const
{
return m_fbxNode->GetName();
}
AZ::u64 FbxNodeWrapper::GetUniqueId() const
{
return m_fbxNode->GetUniqueID();
}
SceneAPI::DataTypes::MatrixType FbxNodeWrapper::EvaluateGlobalTransform()
{
return FbxTypeConverter::ToTransform(m_fbxNode->EvaluateGlobalTransform());
}
Vector3 FbxNodeWrapper::EvaluateLocalTranslation()
{
return FbxTypeConverter::ToVector3(m_fbxNode->EvaluateLocalTranslation());
}
Vector3 FbxNodeWrapper::EvaluateLocalTranslation(FbxTimeWrapper& time)
{
return FbxTypeConverter::ToVector3(m_fbxNode->EvaluateLocalTranslation(time.m_fbxTime));
}
SceneAPI::DataTypes::MatrixType FbxNodeWrapper::EvaluateLocalTransform()
{
return FbxTypeConverter::ToTransform(m_fbxNode->EvaluateLocalTransform());
}
SceneAPI::DataTypes::MatrixType FbxNodeWrapper::EvaluateLocalTransform(FbxTimeWrapper& time)
{
return FbxTypeConverter::ToTransform(m_fbxNode->EvaluateLocalTransform(time.m_fbxTime));
}
Vector3 FbxNodeWrapper::EvaluateLocalRotation()
{
return FbxTypeConverter::ToVector3(m_fbxNode->EvaluateLocalTransform().GetR());
}
Vector3 FbxNodeWrapper::EvaluateLocalRotation(FbxTimeWrapper& time)
{
return FbxTypeConverter::ToVector3(m_fbxNode->EvaluateLocalTransform(time.m_fbxTime).GetR());
}
Vector3 FbxNodeWrapper::GetGeometricTranslation() const
{
return FbxTypeConverter::ToVector3(m_fbxNode->GetGeometricTranslation(FbxNode::eSourcePivot));
}
Vector3 FbxNodeWrapper::GetGeometricScaling() const
{
return FbxTypeConverter::ToVector3(m_fbxNode->GetGeometricScaling(FbxNode::eSourcePivot));
}
Vector3 FbxNodeWrapper::GetGeometricRotation() const
{
return FbxTypeConverter::ToVector3(m_fbxNode->GetGeometricRotation(FbxNode::eSourcePivot));
}
SceneAPI::DataTypes::MatrixType FbxNodeWrapper::GetGeometricTransform() const
{
FbxAMatrix geoTransform(m_fbxNode->GetGeometricTranslation(FbxNode::eSourcePivot),
m_fbxNode->GetGeometricRotation(FbxNode::eSourcePivot), m_fbxNode->GetGeometricScaling(FbxNode::eSourcePivot));
return FbxTypeConverter::ToTransform(geoTransform);
}
const AZStd::shared_ptr<FbxAnimCurveWrapper> FbxNodeWrapper::GetLocalTranslationCurve(const AZStd::shared_ptr<FbxAnimLayerWrapper>& layer,
CurveNodeComponent component) const
{
if (!layer)
{
return nullptr;
}
const char* componentString = nullptr;
switch (component)
{
case Component_X:
componentString = FBXSDK_CURVENODE_COMPONENT_X;
break;
case Component_Y:
componentString = FBXSDK_CURVENODE_COMPONENT_Y;
break;
case Component_Z:
componentString = FBXSDK_CURVENODE_COMPONENT_Z;
break;
default:
break;
}
// If there is available animation curve data of specified component/channel for translation, create and return a wrapped version of it.
return m_fbxNode->LclTranslation.GetCurve(layer->m_fbxAnimLayer, componentString) ?
AZStd::make_shared<FbxAnimCurveWrapper>(m_fbxNode->LclTranslation.GetCurve(layer->m_fbxAnimLayer, componentString)) : nullptr;
}
const AZStd::shared_ptr<FbxAnimCurveWrapper> FbxNodeWrapper::GetLocalRotationCurve(const AZStd::shared_ptr<FbxAnimLayerWrapper>& layer,
CurveNodeComponent component) const
{
if (!layer)
{
return nullptr;
}
const char* componentString = nullptr;
switch (component)
{
case Component_X:
componentString = FBXSDK_CURVENODE_COMPONENT_X;
break;
case Component_Y:
componentString = FBXSDK_CURVENODE_COMPONENT_Y;
break;
case Component_Z:
componentString = FBXSDK_CURVENODE_COMPONENT_Z;
break;
default:
break;
}
// If there is available animation curve data of specified component/channel for rotation, create and return a wrapped version of it.
return m_fbxNode->LclRotation.GetCurve(layer->m_fbxAnimLayer, componentString) ?
AZStd::make_shared<FbxAnimCurveWrapper>(m_fbxNode->LclRotation.GetCurve(layer->m_fbxAnimLayer, componentString)) : nullptr;
}
bool FbxNodeWrapper::IsAnimated() const
{
return FbxAnimUtilities::IsAnimated(m_fbxNode);
}
int FbxNodeWrapper::GetChildCount() const
{
return m_fbxNode->GetChildCount();
}
const std::shared_ptr<SDKNode::NodeWrapper> FbxNodeWrapper::GetChild(int childIndex) const
{
FbxNode* child = m_fbxNode->GetChild(childIndex);
AZ_Assert(child, "Cannot get child FbxNode at index %d", childIndex);
return child ? std::shared_ptr<SDKNode::NodeWrapper>(new FbxNodeWrapper(child)) : nullptr;
}
const std::shared_ptr<FbxMaterialWrapper> FbxNodeWrapper::GetMaterial(int index) const
{
if (index < GetMaterialCount())
{
return std::shared_ptr<FbxMaterialWrapper>(new FbxMaterialWrapper(m_fbxNode->GetMaterial(index)));
}
AZ_Assert(index < GetMaterialCount(), "Invalid material index %d", index);
return nullptr;
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,69 @@
/*
* 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/FbxSDKWrapper/FbxTimeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxMeshWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxPropertyWrapper.h>
#include <SceneAPI/SceneCore/DataTypes/MatrixType.h>
#include <SceneAPI/SDKWrapper/NodeWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxMaterialWrapper;
class FbxAnimLayerWrapper;
class FbxAnimCurveWrapper;
class FbxNodeWrapper : public SDKNode::NodeWrapper
{
public:
AZ_RTTI(FbxNodeWrapper, "{5F1C09D1-791C-41CA-94DB-D7DD2810C859}", SDKNode::NodeWrapper);
FbxNodeWrapper(FbxNode* fbxNode);
~FbxNodeWrapper() override;
int GetMaterialCount() const override;
virtual const char* GetMaterialName(int index) const;
virtual const std::shared_ptr<FbxMaterialWrapper> GetMaterial(int index) const;
virtual const std::shared_ptr<FbxMeshWrapper> GetMesh() const;
virtual const std::shared_ptr<FbxPropertyWrapper> FindProperty(const char* name) const;
virtual bool IsBone() const;
virtual bool IsMesh() const;
const char* GetName() const override;
AZ::u64 GetUniqueId() const override;
virtual SceneAPI::DataTypes::MatrixType EvaluateGlobalTransform();
virtual Vector3 EvaluateLocalTranslation();
virtual Vector3 EvaluateLocalTranslation(FbxTimeWrapper& time);
virtual SceneAPI::DataTypes::MatrixType EvaluateLocalTransform();
virtual SceneAPI::DataTypes::MatrixType EvaluateLocalTransform(FbxTimeWrapper& time);
virtual Vector3 EvaluateLocalRotation();
virtual Vector3 EvaluateLocalRotation(FbxTimeWrapper& time);
virtual Vector3 GetGeometricTranslation() const;
virtual Vector3 GetGeometricScaling() const;
virtual Vector3 GetGeometricRotation() const;
virtual SceneAPI::DataTypes::MatrixType GetGeometricTransform() const;
virtual const AZStd::shared_ptr<FbxAnimCurveWrapper> GetLocalTranslationCurve(const AZStd::shared_ptr<FbxAnimLayerWrapper>& layer, CurveNodeComponent component) const;
virtual const AZStd::shared_ptr<FbxAnimCurveWrapper> GetLocalRotationCurve(const AZStd::shared_ptr<FbxAnimLayerWrapper>& layer, CurveNodeComponent component) const;
int GetChildCount() const override;
const std::shared_ptr<NodeWrapper> GetChild(int childIndex) const override;
virtual bool IsAnimated() const;
protected:
FbxNodeWrapper() = default;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,57 @@
/*
* 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/FbxSDKWrapper/FbxPropertyWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxTypeConverter.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxPropertyWrapper::FbxPropertyWrapper(FbxProperty* fbxProperty)
: m_fbxProperty(fbxProperty)
{
AZ_Assert(fbxProperty, "Invalid FbxProperty to initialize FbxPropertyWrapper");
}
FbxPropertyWrapper::~FbxPropertyWrapper()
{
m_fbxProperty = nullptr;
}
bool FbxPropertyWrapper::IsValid() const
{
return m_fbxProperty->IsValid();
}
Vector3 FbxPropertyWrapper::GetFbxVector3() const
{
return FbxTypeConverter::ToVector3(m_fbxProperty->Get<FbxVector4>());
}
int FbxPropertyWrapper::GetFbxInt() const
{
return aznumeric_caster(m_fbxProperty->Get<FbxInt>());
}
AZStd::string FbxPropertyWrapper::GetFbxString() const
{
return AZStd::string(m_fbxProperty->Get<FbxString>().Buffer());
}
const char* FbxPropertyWrapper::GetEnumValue(int index) const
{
return m_fbxProperty->GetEnumValue(index);
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,39 @@
/*
* 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 <AzCore/Math/Vector3.h>
#include <AzCore/std/string/string.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxPropertyWrapper
{
public:
FbxPropertyWrapper(FbxProperty* fbxProperty);
virtual ~FbxPropertyWrapper();
virtual bool IsValid() const;
virtual Vector3 GetFbxVector3() const;
virtual int GetFbxInt() const;
virtual AZStd::string GetFbxString() const;
virtual const char* GetEnumValue(int index) const;
protected:
FbxProperty* m_fbxProperty;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,200 @@
/*
* 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/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/FbxSDKWrapper/FbxSceneWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxSceneWrapper::FbxSceneWrapper()
: SceneWrapperBase()
, m_fbxManager(nullptr)
, m_fbxImporter(nullptr)
, m_fbxIOSettings(nullptr)
{
}
FbxSceneWrapper::FbxSceneWrapper(FbxScene* fbxScene)
: SceneWrapperBase(fbxScene)
, m_fbxManager(nullptr)
, m_fbxImporter(nullptr)
, m_fbxIOSettings(nullptr)
{
AZ_Assert(fbxScene, "FbxSceneWrapper should have a valid scene to initialize.");
}
FbxSceneWrapper::~FbxSceneWrapper()
{
if (m_fbxScene)
{
m_fbxScene->Destroy();
m_fbxScene = nullptr;
}
if (m_fbxImporter)
{
m_fbxImporter->Destroy();
m_fbxImporter = nullptr;
}
if (m_fbxIOSettings)
{
m_fbxIOSettings->Destroy();
m_fbxIOSettings = nullptr;
}
if (m_fbxManager)
{
m_fbxManager->Destroy();
m_fbxManager = nullptr;
}
}
AZStd::shared_ptr<FbxAxisSystemWrapper> FbxSceneWrapper::GetAxisSystem() const
{
return AZStd::make_shared<FbxAxisSystemWrapper>(m_fbxScene->GetGlobalSettings().GetAxisSystem());
}
AZStd::shared_ptr<FbxSystemUnitWrapper> FbxSceneWrapper::GetSystemUnit() const
{
return AZStd::make_shared<FbxSystemUnitWrapper>(m_fbxScene->GetGlobalSettings().GetSystemUnit());
}
FbxTimeWrapper FbxSceneWrapper::GetTimeLineDefaultDuration() const
{
FbxTimeSpan timeSpan;
m_fbxScene->GetGlobalSettings().GetTimelineDefaultTimeSpan(timeSpan);
return FbxTimeWrapper(timeSpan.GetDuration());
}
const char* FbxSceneWrapper::GetLastSavedApplicationName() const
{
if (m_fbxScene->GetDocumentInfo())
{
return m_fbxScene->GetDocumentInfo()->LastSaved_ApplicationName.Get().Buffer();
}
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Cannot get valid document info from FbxScene");
return nullptr;
}
const char* FbxSceneWrapper::GetLastSavedApplicationVersion() const
{
if (m_fbxScene->GetDocumentInfo())
{
return m_fbxScene->GetDocumentInfo()->LastSaved_ApplicationVersion.Get().Buffer();
}
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Cannot get valid document info from FbxScene");
return nullptr;
}
const std::shared_ptr<SDKNode::NodeWrapper> FbxSceneWrapper::GetRootNode() const
{
return std::shared_ptr<FbxNodeWrapper>(new FbxNodeWrapper(m_fbxScene->GetRootNode()));
}
std::shared_ptr<SDKNode::NodeWrapper> FbxSceneWrapper::GetRootNode()
{
return std::shared_ptr<FbxNodeWrapper>(new FbxNodeWrapper(m_fbxScene->GetRootNode()));
}
int FbxSceneWrapper::GetAnimationStackCount() const
{
return m_fbxScene->GetSrcObjectCount<FbxAnimStack>();
}
const std::shared_ptr<FbxAnimStackWrapper> FbxSceneWrapper::GetAnimationStackAt(int index) const
{
return std::shared_ptr<FbxAnimStackWrapper>(new FbxAnimStackWrapper(FbxCast<FbxAnimStack>(m_fbxScene->GetSrcObject<FbxAnimStack>(index))));
}
bool FbxSceneWrapper::LoadSceneFromFile(const char* fileName)
{
AZ_TracePrintf(SceneAPI::Utilities::LogWindow, "FbxSceneWrapper::LoadSceneFromFile %s", fileName);
AZ_TraceContext("Filename", fileName);
if (!m_fbxManager)
{
m_fbxManager = FbxManager::Create();
if (!m_fbxManager)
{
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Failed to create FbxManager");
return false;
}
}
if (!m_fbxIOSettings)
{
m_fbxIOSettings = FbxIOSettings::Create(m_fbxManager, IOSROOT);
if (!m_fbxIOSettings)
{
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Failed to create FbxIOSettings");
return false;
}
}
m_fbxManager->SetIOSettings(m_fbxIOSettings);
if (!m_fbxImporter)
{
m_fbxImporter = FbxImporter::Create(m_fbxManager, "");
if (!m_fbxImporter)
{
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Failed to create FbxImporter with FbxManager");
return false;
}
}
if (!m_fbxImporter->Initialize(fileName, -1, m_fbxManager->GetIOSettings()))
{
FbxString error = m_fbxImporter->GetStatus().GetErrorString();
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Failed to initialize FbxImporter with fbx file. Error returned: %s", error.Buffer());
return false;
}
// Create a new FBX scene so it can be populated by the imported file.
m_fbxScene = FbxScene::Create(m_fbxManager, s_defaultSceneName);
if (!m_fbxScene)
{
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Failed to create FbxScene");
return false;
}
if (!m_fbxImporter->Import(m_fbxScene))
{
FbxString error = m_fbxImporter->GetStatus().GetErrorString();
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Failed to import FbxScene. Error returned: %s", error.Buffer());
return false;
}
return true;
}
bool FbxSceneWrapper::LoadSceneFromFile(const AZStd::string& fileName)
{
return LoadSceneFromFile(fileName.c_str());
}
void FbxSceneWrapper::Clear()
{
if (m_fbxScene)
{
m_fbxScene->Clear();
}
}
}//namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,62 @@
/*
* 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.
*
*/
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// FBX SDK Wrapper
// provides isolation between AUTODESK FBX SDK and FBX Serializer
// provides necessary APIs for FBX Serializer
//
////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxAnimStackWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxAxisSystemWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxSystemUnitWrapper.h>
#include <SceneAPI/SDKWrapper/SceneWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxSceneWrapper : public SDKScene::SceneWrapperBase
{
public:
AZ_RTTI(FbxSceneWrapper, "{63637E50-BB26-4BE9-AECD-D1168AE2355B}", SDKScene::SceneWrapperBase);
FbxSceneWrapper();
FbxSceneWrapper(fbxsdk::FbxScene* fbxScene);
~FbxSceneWrapper();
bool LoadSceneFromFile(const char* fileName) override;
bool LoadSceneFromFile(const AZStd::string& fileName) override;
virtual AZStd::shared_ptr<FbxSystemUnitWrapper> GetSystemUnit() const;
virtual AZStd::shared_ptr<FbxAxisSystemWrapper> GetAxisSystem() const;
virtual FbxTimeWrapper GetTimeLineDefaultDuration() const;
virtual const char* GetLastSavedApplicationName() const;
virtual const char* GetLastSavedApplicationVersion() const;
const std::shared_ptr<SDKNode::NodeWrapper> GetRootNode() const override;
std::shared_ptr<SDKNode::NodeWrapper> GetRootNode() override;
virtual int GetAnimationStackCount() const;
virtual const std::shared_ptr<FbxAnimStackWrapper> GetAnimationStackAt(int index) const;
void Clear() override;
protected:
FbxManager* m_fbxManager;
FbxImporter* m_fbxImporter;
FbxIOSettings* m_fbxIOSettings;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,86 @@
/*
* 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/std/smart_ptr/make_shared.h>
#include <AzCore/Debug/Trace.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/FbxSDKWrapper/FbxSkinWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxSkinWrapper::FbxSkinWrapper(FbxSkin* fbxSkin)
: m_fbxSkin(fbxSkin)
{
AZ_Assert(fbxSkin, "Invalid FbxSkin input to initialize FbxSkinWrapper");
}
FbxSkinWrapper::~FbxSkinWrapper()
{
m_fbxSkin = nullptr;
}
const char* FbxSkinWrapper::GetName() const
{
return m_fbxSkin->GetName();
}
int FbxSkinWrapper::GetClusterCount() const
{
return m_fbxSkin->GetClusterCount();
}
int FbxSkinWrapper::GetClusterControlPointIndicesCount(int index) const
{
if (index < m_fbxSkin->GetClusterCount())
{
return m_fbxSkin->GetCluster(index)->GetControlPointIndicesCount();
}
AZ_Assert(index < m_fbxSkin->GetClusterCount(), "Invalid skin cluster index %d", index);
return 0;
}
int FbxSkinWrapper::GetClusterControlPointIndex(int clusterIndex, int pointIndex) const
{
bool validIndex = clusterIndex < m_fbxSkin->GetClusterCount() && pointIndex < m_fbxSkin->GetCluster(clusterIndex)->GetControlPointIndicesCount();
if (validIndex)
{
return m_fbxSkin->GetCluster(clusterIndex)->GetControlPointIndices()[pointIndex];
}
AZ_Assert(validIndex, "Invalid skin cluster control point index at cluster index %d control point index %d", clusterIndex, pointIndex);
return -1;
}
double FbxSkinWrapper::GetClusterControlPointWeight(int clusterIndex, int pointIndex) const
{
bool validIndex = clusterIndex < m_fbxSkin->GetClusterCount() && pointIndex < m_fbxSkin->GetCluster(clusterIndex)->GetControlPointIndicesCount();
if (validIndex)
{
return m_fbxSkin->GetCluster(clusterIndex)->GetControlPointWeights()[pointIndex];
}
AZ_Assert(validIndex, "Invalid skin cluster control point weight at cluster index %d control point index %d", clusterIndex, pointIndex);
return 0.0f;
}
AZStd::shared_ptr<const FbxNodeWrapper> FbxSkinWrapper::GetClusterLink(int index) const
{
if (index < m_fbxSkin->GetClusterCount())
{
return AZStd::make_shared<const FbxNodeWrapper>(m_fbxSkin->GetCluster(index)->GetLink());
}
AZ_Assert(index < m_fbxSkin->GetClusterCount(), "Invalid skin cluster index %d", index);
return nullptr;
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,42 @@
/*
* 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 <AzCore/std/smart_ptr/shared_ptr.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxNodeWrapper;
class FbxSkinWrapper
{
public:
FbxSkinWrapper(FbxSkin* fbxSkin);
virtual ~FbxSkinWrapper();
virtual const char* GetName() const;
virtual int GetClusterCount() const;
virtual int GetClusterControlPointIndicesCount(int index) const;
virtual int GetClusterControlPointIndex(int clusterIndex, int pointIndex) const;
virtual double GetClusterControlPointWeight(int clusterIndex, int pointIndex) const;
virtual AZStd::shared_ptr<const FbxNodeWrapper> GetClusterLink(int index) const;
protected:
FbxSkinWrapper() = default;
FbxSkin* m_fbxSkin;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,108 @@
/*
* 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 <AzCore/Debug/Trace.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/FbxSDKWrapper/FbxSystemUnitWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxSystemUnitWrapper::FbxSystemUnitWrapper(const FbxSystemUnit& fbxSystemUnit)
: m_fbxSystemUnit(fbxSystemUnit)
{
}
FbxSystemUnitWrapper::Unit FbxSystemUnitWrapper::GetUnit() const
{
if (m_fbxSystemUnit == FbxSystemUnit::mm)
{
return mm;
}
if (m_fbxSystemUnit == FbxSystemUnit::dm)
{
return dm;
}
if (m_fbxSystemUnit == FbxSystemUnit::cm)
{
return cm;
}
if (m_fbxSystemUnit == FbxSystemUnit::m)
{
return m;
}
if (m_fbxSystemUnit == FbxSystemUnit::km)
{
return km;
}
if (m_fbxSystemUnit == FbxSystemUnit::Inch)
{
return inch;
}
if (m_fbxSystemUnit == FbxSystemUnit::Foot)
{
return foot;
}
if (m_fbxSystemUnit == FbxSystemUnit::Mile)
{
return mile;
}
if (m_fbxSystemUnit == FbxSystemUnit::Yard)
{
return yard;
}
AZ_TracePrintf(SceneAPI::Utilities::WarningWindow, "Unrecognized current unit type");
return unknown;
}
float FbxSystemUnitWrapper::GetConversionFactorTo(Unit to)
{
FbxSystemUnit targetUnit;
switch (to)
{
case mm:
targetUnit = FbxSystemUnit::mm;
break;
case dm:
targetUnit = FbxSystemUnit::dm;
break;
case cm:
targetUnit = FbxSystemUnit::cm;
break;
case m:
targetUnit = FbxSystemUnit::m;
break;
case km:
targetUnit = FbxSystemUnit::km;
break;
case inch:
targetUnit = FbxSystemUnit::Inch;
break;
case foot:
targetUnit = FbxSystemUnit::Foot;
break;
case mile:
targetUnit = FbxSystemUnit::Mile;
break;
case yard:
targetUnit = FbxSystemUnit::Yard;
break;
default:
AZ_TracePrintf(SceneAPI::Utilities::WarningWindow, "Unrecognized unit conversion target type");
targetUnit = FbxSystemUnit::m;
}
return aznumeric_caster(m_fbxSystemUnit.GetConversionFactorTo(targetUnit));
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,49 @@
/*
* 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>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxSystemUnitWrapper
{
public:
enum Unit
{
mm,
dm,
cm,
m,
km,
inch,
foot,
mile,
yard,
unknown
};
FbxSystemUnitWrapper() = default;
FbxSystemUnitWrapper(const FbxSystemUnit& fbxSystemUnit);
virtual ~FbxSystemUnitWrapper() = default;
virtual Unit GetUnit() const;
virtual float GetConversionFactorTo(Unit to);
protected:
FbxSystemUnit m_fbxSystemUnit;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,45 @@
/*
* 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/Debug/Trace.h>
#include <SceneAPI/FbxSDKWrapper/FbxTimeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxTimeSpanWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxTimeSpanWrapper::FbxTimeSpanWrapper(const FbxTimeSpan& fbxTimeSpan)
: m_fbxTimeSpan(fbxTimeSpan)
{
}
FbxTimeWrapper FbxTimeSpanWrapper::GetStartTime() const
{
return FbxTimeWrapper(m_fbxTimeSpan.GetStart());
}
FbxTimeWrapper FbxTimeSpanWrapper::GetStopTime() const
{
return FbxTimeWrapper(m_fbxTimeSpan.GetStop());
}
double FbxTimeSpanWrapper::GetFrameRate() const
{
return FbxTimeWrapper(m_fbxTimeSpan.GetStart()).GetFrameRate();
}
int64_t FbxTimeSpanWrapper::GetNumFrames() const
{
return GetStopTime().GetFrameCount() - GetStartTime().GetFrameCount() + 1;
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,37 @@
/*
* 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/FbxSDKWrapper/FbxTimeWrapper.h>
#include <fbxsdk.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxTimeSpanWrapper
{
public:
FbxTimeSpanWrapper(const FbxTimeSpan& fbxTimeSpan);
virtual ~FbxTimeSpanWrapper() = default;
virtual FbxTimeWrapper GetStartTime() const;
virtual FbxTimeWrapper GetStopTime() const;
virtual double GetFrameRate() const;
int64_t GetNumFrames() const;
protected:
FbxTimeSpan m_fbxTimeSpan;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,76 @@
/*
* 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/Debug/Trace.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/FbxSDKWrapper/FbxTimeWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxTimeWrapper::FbxTimeWrapper() : m_fbxTime(FBXSDK_TIME_INFINITE)
{
}
FbxTimeWrapper::FbxTimeWrapper(const FbxTime& fbxTime) : m_fbxTime(fbxTime)
{
}
FbxTimeWrapper::~FbxTimeWrapper()
{
}
void FbxTimeWrapper::SetFrame(int64_t frames, TimeMode timeMode)
{
m_fbxTime.SetFrame(static_cast<FbxLongLong>(frames), GetFbxTimeMode(timeMode));
}
void FbxTimeWrapper::SetTime(double time)
{
m_fbxTime.SetSecondDouble(time);
}
double FbxTimeWrapper::GetFrameRate() const
{
return m_fbxTime.GetFrameRate(m_fbxTime.GetGlobalTimeMode());
}
int64_t FbxTimeWrapper::GetFrameCount() const
{
return static_cast<int64_t>(m_fbxTime.GetFrameCount());
}
double FbxTimeWrapper::GetTime() const
{
return m_fbxTime.GetSecondDouble();
}
FbxTime::EMode FbxTimeWrapper::GetFbxTimeMode(TimeMode timeMode) const
{
switch (timeMode)
{
case frames60:
return FbxTime::eFrames60;
case frames30:
return FbxTime::eFrames30;
case frames24:
return FbxTime::eFrames24;
case defaultMode:
return FbxTime::eDefaultMode;
default:
AZ_TracePrintf(SceneAPI::Utilities::WarningWindow, "Unsupported frame rate");
return FbxTime::eDefaultMode;
}
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,52 @@
/*
* 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 <stdint.h>
#include <fbxsdk.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxTimeWrapper
{
friend class FbxNodeWrapper;
friend class FbxAnimCurveWrapper;
public:
enum TimeMode
{
defaultMode,
frames60,
frames30,
frames24,
eModesCount
};
FbxTimeWrapper();
FbxTimeWrapper(const FbxTime& fbxTime);
virtual ~FbxTimeWrapper();
virtual void SetFrame(int64_t frames, TimeMode timeMode = defaultMode);
virtual void SetTime(double time);
virtual double GetFrameRate() const;
virtual int64_t GetFrameCount() const;
virtual double GetTime() const;
protected:
FbxTime::EMode GetFbxTimeMode(TimeMode timeMode) const;
FbxTime m_fbxTime;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,64 @@
/*
* 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/FbxSDKWrapper/FbxTypeConverter.h>
namespace AZ
{
namespace FbxSDKWrapper
{
Vector2 FbxTypeConverter::ToVector2(const FbxVector2& vector)
{
return Vector2(static_cast<float>(vector[0]),
static_cast<float>(vector[1]));
}
Vector3 FbxTypeConverter::ToVector3(const FbxVector4& vector)
{
// Note: FbxVector4[x] is of type FbxDouble and aznumeric_caster does not accept it as cast from type.
return Vector3(static_cast<float>(vector[0]),
static_cast<float>(vector[1]),
static_cast<float>(vector[2]));
}
SceneAPI::DataTypes::MatrixType FbxTypeConverter::ToTransform(const FbxAMatrix& matrix)
{
SceneAPI::DataTypes::MatrixType transform;
for (int row = 0; row < 3; ++row)
{
FbxVector4 line = matrix.GetColumn(row);
for (int column = 0; column < 4; ++column)
{
// Note: FbxVector4[x] is of type FbxDouble and aznumeric_caster does not accept it as cast from type.
transform.SetElement(row, column, static_cast<float>(line[column]));
}
}
return transform;
}
SceneAPI::DataTypes::MatrixType FbxTypeConverter::ToTransform(const FbxMatrix& matrix)
{
// This implementation ignores the last row, effectively assuming it to be (0,0,0,1)
SceneAPI::DataTypes::MatrixType transform;
for (int row = 0; row < 3; ++row)
{
FbxVector4 line = matrix.GetColumn(row);
for (int column = 0; column < 4; ++column)
{
// Note: FbxVector4[x] is of type FbxDouble and aznumeric_caster does not accept it as cast from type.
transform.SetElement(row, column, static_cast<float>(line[column]));
}
}
return transform;
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,32 @@
/*
* 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 <AzCore/Math/Vector2.h>
#include <AzCore/Math/Vector3.h>
#include <SceneAPI/SceneCore/DataTypes/MatrixType.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxTypeConverter
{
public:
static Vector2 ToVector2(const FbxVector2& vector);
static Vector3 ToVector3(const FbxVector4& vector);
static SceneAPI::DataTypes::MatrixType ToTransform(const FbxAMatrix& matrix);
static SceneAPI::DataTypes::MatrixType ToTransform(const FbxMatrix& matrix);
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,53 @@
/*
* 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/FbxSDKWrapper/FbxUVWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxLayerElementUtilities.h>
#include <SceneAPI/FbxSDKWrapper/FbxTypeConverter.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxUVWrapper::FbxUVWrapper(FbxGeometryElementUV* fbxUV)
: m_fbxUV(fbxUV)
{
AZ_Assert(fbxUV, "Invalid FbxGeometryElementUV to initialize FbxUVWrapper")
}
FbxUVWrapper::~FbxUVWrapper()
{
m_fbxUV = nullptr;
}
const char* FbxUVWrapper::GetName() const
{
if (m_fbxUV)
{
return m_fbxUV->GetName();
}
return nullptr;
}
Vector2 FbxUVWrapper::GetElementAt(int polygonIndex, int polygonVertexIndex, int controlPointIndex) const
{
FbxVector2 uv;
FbxLayerElementUtilities::GetGeometryElement(uv, m_fbxUV, polygonIndex, polygonVertexIndex, controlPointIndex);
return FbxTypeConverter::ToVector2(uv);
}
bool FbxUVWrapper::IsValid() const
{
return m_fbxUV != nullptr;
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,37 @@
/*
* 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 <AzCore/Math/Vector2.h>
#include <SceneAPI/FbxSDKWrapper/FbxLayerElementUtilities.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxUVWrapper
{
public:
FbxUVWrapper(FbxGeometryElementUV* fbxUV);
~FbxUVWrapper();
Vector2 GetElementAt(int polygonIndex, int polygonVertexIndex, int controlPointIndex) const;
const char* GetName() const;
bool IsValid() const;
protected:
FbxGeometryElementUV* m_fbxUV;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,58 @@
/*
* 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/FbxSDKWrapper/FbxVertexBitangentWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxLayerElementUtilities.h>
#include <SceneAPI/FbxSDKWrapper/FbxTypeConverter.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxVertexBitangentWrapper::FbxVertexBitangentWrapper(FbxGeometryElementBinormal* fbxBitangent)
: m_fbxBitangent(fbxBitangent)
{
AZ_Assert(fbxBitangent, "Invalid FbxGeometryElementBinormal to initialize FbxVertexBitangentWrapper")
}
FbxVertexBitangentWrapper::~FbxVertexBitangentWrapper()
{
m_fbxBitangent = nullptr;
}
const char* FbxVertexBitangentWrapper::GetName() const
{
if (m_fbxBitangent)
{
return m_fbxBitangent->GetName();
}
return "";
}
Vector3 FbxVertexBitangentWrapper::GetElementAt(int polygonIndex, int polygonVertexIndex, int controlPointIndex) const
{
FbxVector4 bitangent;
FbxLayerElementUtilities::GetGeometryElement(bitangent, m_fbxBitangent, polygonIndex, polygonVertexIndex, controlPointIndex);
return FbxTypeConverter::ToVector3(bitangent);
}
bool FbxVertexBitangentWrapper::IsValid() const
{
return m_fbxBitangent != nullptr;
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,39 @@
/*
* 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 <AzCore/Math/Vector3.h>
#include <SceneAPI/FbxSDKWrapper/FbxLayerElementUtilities.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxVertexBitangentWrapper
{
public:
FbxVertexBitangentWrapper(FbxGeometryElementBinormal* fbxBitangent);
~FbxVertexBitangentWrapper();
Vector3 GetElementAt(int polygonIndex, int polygonVertexIndex, int controlPointIndex) const;
const char* GetName() const;
bool IsValid() const;
protected:
FbxGeometryElementBinormal* m_fbxBitangent;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,79 @@
/*
* 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/FbxSDKWrapper/FbxVertexColorWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxLayerElementUtilities.h>
#include <SceneAPI/FbxSDKWrapper/FbxTypeConverter.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxColorWrapper::FbxColorWrapper(FbxColor& fbxColor)
: m_fbxColor(fbxColor)
{
}
float FbxColorWrapper::GetR() const
{
return aznumeric_caster(m_fbxColor.mRed);
}
float FbxColorWrapper::GetG() const
{
return aznumeric_caster(m_fbxColor.mGreen);
}
float FbxColorWrapper::GetB() const
{
return aznumeric_caster(m_fbxColor.mBlue);
}
float FbxColorWrapper::GetAlpha() const
{
return aznumeric_caster(m_fbxColor.mAlpha);
}
FbxVertexColorWrapper::FbxVertexColorWrapper(FbxGeometryElementVertexColor* fbxVertexColor)
: m_fbxVertexColor(fbxVertexColor)
{
AZ_Assert(m_fbxVertexColor, "Invalid FbxGeometryElementVertexColor to initialie FbxVertexColorWrapper");
}
FbxVertexColorWrapper::~FbxVertexColorWrapper()
{
m_fbxVertexColor = nullptr;
}
const char* FbxVertexColorWrapper::GetName() const
{
if (m_fbxVertexColor)
{
return m_fbxVertexColor->GetName();
}
return nullptr;
}
FbxColorWrapper FbxVertexColorWrapper::GetElementAt(int polygonIndex, int polygonVertexIndex, int controlPointIndex) const
{
FbxColor color;
FbxLayerElementUtilities::GetGeometryElement(color, m_fbxVertexColor, polygonIndex, polygonVertexIndex, controlPointIndex);
return FbxColorWrapper(color);
}
bool FbxVertexColorWrapper::IsValid() const
{
return m_fbxVertexColor != nullptr;
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,49 @@
/*
* 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/FbxSDKWrapper/FbxLayerElementUtilities.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxColorWrapper
{
public:
FbxColorWrapper(FbxColor& fbxColor);
float GetR() const;
float GetG() const;
float GetB() const;
float GetAlpha() const;
protected:
FbxColor m_fbxColor;
};
class FbxVertexColorWrapper
{
public:
FbxVertexColorWrapper(FbxGeometryElementVertexColor* fbxVertexColor);
~FbxVertexColorWrapper();
FbxColorWrapper GetElementAt(int polygonIndex, int polygonVertexIndex, int controlPointIndex) const;
const char* GetName() const;
bool IsValid() const;
protected:
FbxGeometryElementVertexColor* m_fbxVertexColor;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,59 @@
/*
* 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/FbxSDKWrapper/FbxVertexTangentWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxLayerElementUtilities.h>
#include <SceneAPI/FbxSDKWrapper/FbxTypeConverter.h>
namespace AZ
{
namespace FbxSDKWrapper
{
FbxVertexTangentWrapper::FbxVertexTangentWrapper(FbxGeometryElementTangent* fbxTangent)
: m_fbxTangent(fbxTangent)
{
AZ_Assert(fbxTangent, "Invalid FbxGeometryElementTangent to initialize FbxVertexTangentWrapper")
}
FbxVertexTangentWrapper::~FbxVertexTangentWrapper()
{
m_fbxTangent = nullptr;
}
const char* FbxVertexTangentWrapper::GetName() const
{
if (m_fbxTangent)
{
return m_fbxTangent->GetName();
}
return "";
}
Vector3 FbxVertexTangentWrapper::GetElementAt(int polygonIndex, int polygonVertexIndex, int controlPointIndex) const
{
FbxVector4 tangent;
FbxLayerElementUtilities::GetGeometryElement(tangent, m_fbxTangent, polygonIndex, polygonVertexIndex, controlPointIndex);
return FbxTypeConverter::ToVector3(tangent);
}
bool FbxVertexTangentWrapper::IsValid() const
{
return m_fbxTangent != nullptr;
}
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,39 @@
/*
* 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 <AzCore/Math/Vector3.h>
#include <SceneAPI/FbxSDKWrapper/FbxLayerElementUtilities.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class FbxVertexTangentWrapper
{
public:
FbxVertexTangentWrapper(FbxGeometryElementTangent* fbxTangent);
~FbxVertexTangentWrapper();
Vector3 GetElementAt(int polygonIndex, int polygonVertexIndex, int controlPointIndex) const;
const char* GetName() const;
bool IsValid() const;
protected:
FbxGeometryElementTangent* m_fbxTangent;
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,32 @@
#pragma once
/*
* 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/FbxSDKWrapper/FbxAnimStackWrapper.h>
#include <AzTest/AzTest.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class MockFbxAnimStackWrapper
: public FbxAnimStackWrapper
{
public:
MOCK_CONST_METHOD0(GetMemberCount,
int());
MOCK_CONST_METHOD1(GetAnimationLayerAt,
FbxAnimLayer * (int index));
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,32 @@
#pragma once
/*
* 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 <AzTest/AzTest.h>
#include <SceneAPI/FbxSDKWrapper/FbxAxisSystemWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class MockFbxAxisSystemWrapper
: public FbxAxisSystemWrapper
{
public:
MOCK_CONST_METHOD1(GetUpVector,
UpVector(int));
MOCK_METHOD1(CalculateConversionTransform,
Transform(UpVector));
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,38 @@
#pragma once
/*
* 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 <AzTest/AzTest.h>
#include <SceneAPI/FbxSDKWrapper/FbxMaterialWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class MockFbxMaterialWrapper
: public FbxMaterialWrapper
{
public:
MOCK_CONST_METHOD0(GetName,
std::string());
MOCK_CONST_METHOD1(GetTextureFileName,
std::string(const char* textureType));
MOCK_CONST_METHOD1(GetTextureFileName,
std::string(const std::string& textureType));
MOCK_CONST_METHOD1(GetTextureFileName,
std::string(MaterialMapType textureType));
MOCK_CONST_METHOD0(IsNoDraw,
bool());
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,56 @@
#pragma once
/*
* 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 <AzTest/AzTest.h>
#include <SceneAPI/FbxSDKWrapper/FbxMeshWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class MockFbxMeshWrapper
: public FbxMeshWrapper
{
public:
MOCK_CONST_METHOD0(GetDeformerCount,
int());
MOCK_CONST_METHOD1(GetSkin,
AZStd::shared_ptr<const FbxSkinWrapper>(int index));
MOCK_CONST_METHOD1(GetMaterialIndices,
bool(FbxLayerElementArrayTemplate<int>**));
MOCK_CONST_METHOD0(GetControlPointsCount,
int());
MOCK_CONST_METHOD0(GetControlPoints,
AZStd::vector<Vector3>());
MOCK_CONST_METHOD0(GetPolygonCount,
int());
MOCK_CONST_METHOD1(GetPolygonSize,
int(int));
MOCK_CONST_METHOD1(GetPolygonVertics,
int(int index));
MOCK_CONST_METHOD1(GetPolygonVertexIndex,
int(int));
MOCK_CONST_METHOD1(GetElementUV,
FbxUVWrapper(int));
MOCK_CONST_METHOD0(GetElementUVCount,
int());
MOCK_CONST_METHOD1(GetElementVertexColor,
FbxVertexColorWrapper(int));
MOCK_CONST_METHOD0(GetElementVertexColorCount,
int());
MOCK_CONST_METHOD3(GetPolygonVertexNormal,
bool(int, int, Vector3&));
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,67 @@
#pragma once
/*
* 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/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxTimeWrapper.h>
#include <AzTest/AzTest.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class MockFbxNodeWrapper
: public FbxNodeWrapper
{
public:
MOCK_CONST_METHOD0(GetMaterialCount,
int());
MOCK_CONST_METHOD1(GetMaterialName,
const char*(int index));
MOCK_CONST_METHOD1(GetMaterial,
const std::shared_ptr<FbxMaterialWrapper>(int index));
MOCK_CONST_METHOD0(GetMesh,
const std::shared_ptr<FbxMeshWrapper>());
MOCK_CONST_METHOD1(FindProperty,
const std::shared_ptr<FbxPropertyWrapper>(const char* name));
MOCK_CONST_METHOD0(IsBone,
bool());
MOCK_CONST_METHOD0(GetName,
const char*());
MOCK_METHOD0(EvaluateGlobalTransform,
Transform());
MOCK_METHOD0(EvaluateLocalTranslation,
Vector3());
MOCK_METHOD1(EvaluateLocalTranslation,
Vector3(FbxTimeWrapper& time));
MOCK_METHOD0(EvaluateLocalTransform,
Transform());
MOCK_METHOD1(EvaluateLocalTransform,
Transform(FbxTimeWrapper& time));
MOCK_CONST_METHOD0(GetGeometricTranslation,
Vector3());
MOCK_CONST_METHOD0(GetGeometricScaling,
Vector3());
MOCK_CONST_METHOD0(GetGeometricRotation,
Vector3());
MOCK_CONST_METHOD0(GetGeometricTransform,
Transform());
MOCK_CONST_METHOD0(GetChildCount,
int());
MOCK_CONST_METHOD1(GetChild,
const std::shared_ptr<FbxNodeWrapper>(int childIndex));
MOCK_CONST_METHOD0(IsAnimated,
bool());
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,42 @@
#pragma once
/*
* 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/FbxSDKWrapper/FbxPropertyWrapper.h>
#include <AzTest/AzTest.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class MockFbxPropertyWrapper
: public FbxPropertyWrapper
{
public:
MockFbxPropertyWrapper()
: FbxPropertyWrapper(new FbxProperty())
{
}
MOCK_CONST_METHOD0(IsValid,
bool());
MOCK_CONST_METHOD0(GetFbxVector4,
Vector4());
MOCK_CONST_METHOD0(GetFbxInt,
FbxInt());
MOCK_CONST_METHOD0(GetFbxString,
AZStd::string());
MOCK_CONST_METHOD1(GetEnumValue,
const char*(int index));
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,55 @@
#pragma once
/*
* 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/FbxSDKWrapper/FbxSceneWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxTimeWrapper.h>
#include <AzTest/AzTest.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class MockFbxSceneWrapper
: public FbxSceneWrapper
{
public:
virtual ~MockFbxSceneWrapper() = default;
MOCK_METHOD1(LoadSceneFromFile,
bool(const char* fileName));
MOCK_METHOD1(LoadSceneFromFile,
bool(const std::string& fileName));
MOCK_CONST_METHOD0(GetSystemUnit,
AZStd::shared_ptr<FbxSystemUnitWrapper>());
MOCK_CONST_METHOD0(GetAxisSystem,
AZStd::shared_ptr<FbxAxisSystemWrapper>());
MOCK_CONST_METHOD0(GetTimeLineDefaultDuration,
FbxTimeWrapper());
MOCK_CONST_METHOD0(GetLastSavedApplicationName,
const char*());
MOCK_CONST_METHOD0(GetLastSavedApplicationVersion,
const char*());
MOCK_CONST_METHOD0(GetRootNode,
const std::shared_ptr<FbxNodeWrapper>());
MOCK_METHOD0(GetRootNode,
std::shared_ptr<FbxNodeWrapper>());
MOCK_CONST_METHOD0(GetAnimationStackCount,
int());
MOCK_CONST_METHOD1(GetAnimationStackAt,
const std::shared_ptr<FbxAnimStackWrapper>(int index));
MOCK_METHOD0(Clear,
void());
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,40 @@
#pragma once
/*
* 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/FbxSdkWrapper/FbxSkinWrapper.h>
#include <AzTest/AzTest.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class MockFbxSkinWrapper
: public FbxSkinWrapper
{
public:
MOCK_CONST_METHOD0(GetName,
const char*());
MOCK_CONST_METHOD0(GetClusterCount,
int());
MOCK_CONST_METHOD1(GetClusterControlPointIndicesCount,
int(int index));
MOCK_CONST_METHOD2(GetClusterControlPointIndices,
int(int clusterIndex, int pointIndex));
MOCK_CONST_METHOD2(GetClusterControlPointWeights,
double(int clusterIndex, int pointIndex));
MOCK_CONST_METHOD1(GetClusterLink,
AZStd::shared_ptr<const FbxNodeWrapper>(int index));
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,32 @@
#pragma once
/*
* 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 <AzTest/AzTest.h>
#include <SceneAPI/FbxSDKWrapper/FbxSystemUnitWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class MockFbxSystemUnitWrapper
: public FbxSystemUnitWrapper
{
public:
MOCK_CONST_METHOD0(GetUnit,
Unit());
MOCK_METHOD1(GetConversionFactorTo,
float(Unit));
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,34 @@
#pragma once
/*
* 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 <AzTest/AzTest.h>
#include <SceneAPI/FbxSDKWrapper/FbxTimeWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class MockFbxTimeWrapper
: public FbxTimeWrapper
{
public:
MOCK_METHOD2(SetFrame,
void(int64_t, TimeMode));
MOCK_CONST_METHOD0(GetFrameRate,
double());
MOCK_CONST_METHOD0(GetFrameCount,
int64_t());
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,34 @@
#pragma once
/*
* 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/FbxSDKWrapper/FbxUVWrapper.h>
#include <AzTest/AzTest.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class MockFbxUVWrapper
: public FbxUVWrapper
{
public:
MOCK_CONST_METHOD3(GetElementAt,
Vector2(int, int, int));
MOCK_CONST_METHOD0(GetName,
const char*());
MOCK_CONST_METHOD0(IsValid,
bool());
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,35 @@
#pragma once
/*
* 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 <AzTest/AzTest.h>
#include <SceneAPI/FbxSDKWrapper/FbxVertexColorWrapper.h>
namespace AZ
{
namespace FbxSDKWrapper
{
class MockFbxVertexColorWrapper
: public FbxVertexColorWrapper
{
public:
MOCK_CONST_METHOD3(GetElementAt,
FbxColorWrapper(int, int, int));
MOCK_CONST_METHOD0(GetName,
const char*());
MOCK_CONST_METHOD0(IsValid,
bool());
};
} // namespace FbxSDKWrapper
} // namespace AZ
@@ -0,0 +1,12 @@
#
# 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.
#
@@ -0,0 +1,12 @@
#
# 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.
#
@@ -0,0 +1,16 @@
#
# 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.
#
set(LY_BUILD_DEPENDENCIES
PUBLIC
3rdParty::AssImp
)
set(LY_COMPILE_DEFINITIONS PUBLIC ASSET_IMPORTER_SDK_SUPPORTED_TRAIT)
@@ -0,0 +1,69 @@
#
# 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.
#
set(FILES
FbxSceneWrapper.cpp
FbxAnimStackWrapper.cpp
FbxAnimLayerWrapper.cpp
FbxAnimCurveNodeWrapper.cpp
FbxAnimCurveWrapper.cpp
FbxNodeWrapper.cpp
FbxMeshWrapper.cpp
FbxSkinWrapper.cpp
FbxPropertyWrapper.cpp
FbxMaterialWrapper.cpp
FbxTimeWrapper.cpp
FbxTimeSpanWrapper.cpp
FbxTypeConverter.cpp
FbxAxisSystemWrapper.cpp
FbxSystemUnitWrapper.cpp
FbxVertexColorWrapper.cpp
FbxVertexTangentWrapper.cpp
FbxVertexBitangentWrapper.cpp
FbxUVWrapper.cpp
FbxBlendShapeWrapper.cpp
FbxBlendShapeChannelWrapper.cpp
FbxLayerElementUtilities.inl
FbxSceneWrapper.h
FbxAnimStackWrapper.h
FbxAnimLayerWrapper.h
FbxAnimCurveNodeWrapper.h
FbxAnimCurveWrapper.h
FbxNodeWrapper.h
FbxMeshWrapper.h
FbxSkinWrapper.h
FbxPropertyWrapper.h
FbxMaterialWrapper.h
FbxTimeWrapper.h
FbxTimeSpanWrapper.h
FbxTypeConverter.h
FbxAxisSystemWrapper.h
FbxSystemUnitWrapper.h
FbxVertexColorWrapper.h
FbxVertexTangentWrapper.h
FbxVertexBitangentWrapper.h
FbxUVWrapper.h
FbxBlendShapeWrapper.h
FbxBlendShapeChannelWrapper.h
FbxLayerElementUtilities.h
Mocks/MockFbxAnimStackWrapper.h
Mocks/MockFbxAxisSystemWrapper.h
Mocks/MockFbxMaterialWrapper.h
Mocks/MockFbxMeshWrapper.h
Mocks/MockFbxNodeWrapper.h
Mocks/MockFbxPropertyWrapper.h
Mocks/MockFbxSceneWrapper.h
Mocks/MockFbxSkinWrapper.h
Mocks/MockFbxSystemUnitWrapper.h
Mocks/MockFbxTimeWrapper.h
Mocks/MockFbxUVWrapper.h
Mocks/MockFbxVertexColorWrapper.h
)
@@ -0,0 +1,76 @@
#
# 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.
#
if (NOT PAL_TRAIT_BUILD_HOST_TOOLS)
return()
endif()
ly_add_target(
NAME FbxSceneBuilder.Static STATIC
NAMESPACE AZ
FILES_CMAKE
fbxscenebuilder_files.cmake
Platform/${PAL_PLATFORM_NAME}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
COMPILE_DEFINITIONS
PRIVATE
FBX_SCENE_BUILDER_EXPORTS
INCLUDE_DIRECTORIES
PUBLIC
../..
BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
AZ::AzFramework
PUBLIC
AZ::AzToolsFramework
AZ::FbxSDKWrapper
AZ::SceneCore
AZ::SceneData
)
ly_add_target(
NAME FbxSceneBuilder MODULE
NAMESPACE AZ
FILES_CMAKE
fbxscenebuilder_shared_files.cmake
COMPILE_DEFINITIONS
PRIVATE
FBX_SCENE_BUILDER_EXPORTS
INCLUDE_DIRECTORIES
PUBLIC
../..
BUILD_DEPENDENCIES
PUBLIC
AZ::FbxSceneBuilder.Static
PRIVATE
AZ::AzCore
)
ly_add_dependencies(AssetBuilder AZ::FbxSceneBuilder)
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
ly_add_target(
NAME FbxSceneBuilder.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
NAMESPACE AZ
FILES_CMAKE
fbxscenebuilder_testing_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
Tests
BUILD_DEPENDENCIES
PRIVATE
AZ::AzTest
AZ::FbxSceneBuilder
)
ly_add_googletest(
NAME AZ::FbxSceneBuilder.Tests
)
endif()
@@ -0,0 +1,158 @@
/*
* 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.
*
*/
#if !defined(AZ_MONOLITHIC_BUILD)
#include <AzCore/Component/Component.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/Module/Environment.h>
#include <SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h>
#include <SceneAPI/FbxSceneBuilder/FbxImporter.h>
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpColorStreamImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpMaterialImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpMeshImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpUvMapImporter.h>
#endif
#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
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
static AZ::SceneAPI::FbxSceneImporter::FbxImportRequestHandler* g_fbxImporter = nullptr;
static AZStd::vector<AZ::ComponentDescriptor*> g_componentDescriptors;
void Initialize()
{
// Currently it's still needed to explicitly create an instance of this instead of letting
// it be a normal component. This is because ResourceCompilerScene needs to return
// the list of available extensions before it can start the application.
if (!g_fbxImporter)
{
g_fbxImporter = aznew AZ::SceneAPI::FbxSceneImporter::FbxImportRequestHandler();
g_fbxImporter->Activate();
}
}
void Reflect(AZ::SerializeContext* /*context*/)
{
// Descriptor registration is done in Reflect instead of Initialize because the ResourceCompilerScene initializes the libraries before
// there's an application.
using namespace AZ::SceneAPI;
using namespace AZ::SceneAPI::FbxSceneBuilder;
if (g_componentDescriptors.empty())
{
// Global importer and behavior
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());
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
g_componentDescriptors.push_back(AssImpColorStreamImporter::CreateDescriptor());
g_componentDescriptors.push_back(AssImpMaterialImporter::CreateDescriptor());
g_componentDescriptors.push_back(AssImpMeshImporter::CreateDescriptor());
g_componentDescriptors.push_back(AssImpTransformImporter::CreateDescriptor());
g_componentDescriptors.push_back(AssImpUvMapImporter::CreateDescriptor());
#endif
for (AZ::ComponentDescriptor* descriptor : g_componentDescriptors)
{
AZ::ComponentApplicationBus::Broadcast(&AZ::ComponentApplicationBus::Handler::RegisterComponentDescriptor, descriptor);
}
}
}
void ReflectBehavior([[maybe_unused]] AZ::BehaviorContext* context)
{
// stub in until LYN-1284 is done
}
void Activate()
{
}
void Deactivate()
{
}
void Uninitialize()
{
if (!g_componentDescriptors.empty())
{
for (AZ::ComponentDescriptor* descriptor : g_componentDescriptors)
{
descriptor->ReleaseDescriptor();
}
g_componentDescriptors.clear();
g_componentDescriptors.shrink_to_fit();
}
if (g_fbxImporter)
{
g_fbxImporter->Deactivate();
delete g_fbxImporter;
g_fbxImporter = nullptr;
}
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
extern "C" AZ_DLL_EXPORT void InitializeDynamicModule(void* env)
{
AZ::Environment::Attach(static_cast<AZ::EnvironmentInstance>(env));
AZ::SceneAPI::FbxSceneBuilder::Initialize();
}
extern "C" AZ_DLL_EXPORT void Reflect(AZ::SerializeContext* context)
{
AZ::SceneAPI::FbxSceneBuilder::Reflect(context);
}
extern "C" AZ_DLL_EXPORT void ReflectBehavior(AZ::BehaviorContext* context)
{
AZ::SceneAPI::FbxSceneBuilder::ReflectBehavior(context);
}
extern "C" AZ_DLL_EXPORT void UninitializeDynamicModule()
{
AZ::SceneAPI::FbxSceneBuilder::Uninitialize();
AZ::Environment::Detach();
}
#endif // !defined(AZ_MONOLITHIC_BUILD)
@@ -0,0 +1,78 @@
/*
* 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 <AzFramework/StringFunc/StringFunc.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Events/CallProcessorBus.h>
#include <SceneAPI/SceneCore/Events/ImportEventContext.h>
#include <SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneImporter
{
const char* FbxImportRequestHandler::s_extension = ".fbx";
void FbxImportRequestHandler::Activate()
{
BusConnect();
}
void FbxImportRequestHandler::Deactivate()
{
BusDisconnect();
}
void FbxImportRequestHandler::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxImportRequestHandler, SceneCore::BehaviorComponent>()->Version(1);
}
}
void FbxImportRequestHandler::GetSupportedFileExtensions(AZStd::unordered_set<AZStd::string>& extensions)
{
extensions.insert(s_extension);
}
Events::LoadingResult FbxImportRequestHandler::LoadAsset(Containers::Scene& scene, const AZStd::string& path, const Uuid& guid, [[maybe_unused]] RequestingApplication requester)
{
if (!AzFramework::StringFunc::Path::IsExtension(path.c_str(), s_extension))
{
return Events::LoadingResult::Ignored;
}
scene.SetSource(path, guid);
// Push contexts
Events::ProcessingResultCombiner contextResult;
contextResult += Events::Process<Events::PreImportEventContext>(path);
contextResult += Events::Process<Events::ImportEventContext>(path, scene);
contextResult += Events::Process<Events::PostImportEventContext>(scene);
if (contextResult.GetResult() == Events::ProcessingResult::Success)
{
return Events::LoadingResult::AssetLoaded;
}
else
{
return Events::LoadingResult::AssetFailure;
}
}
} // namespace Import
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,46 @@
/*
* 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/SceneCore/Components/BehaviorComponent.h>
#include <SceneAPI/SceneCore/Events/AssetImportRequest.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneImporter
{
class FbxImportRequestHandler
: public SceneCore::BehaviorComponent
, public Events::AssetImportRequestBus::Handler
{
public:
AZ_COMPONENT(FbxImportRequestHandler, "{9F4B189C-0A96-4F44-A5F0-E087FF1561F8}", SceneCore::BehaviorComponent);
~FbxImportRequestHandler() override = default;
void Activate() override;
void Deactivate() override;
static void Reflect(ReflectContext* context);
void GetSupportedFileExtensions(AZStd::unordered_set<AZStd::string>& extensions) override;
Events::LoadingResult LoadAsset(Containers::Scene& scene, const AZStd::string& path, const Uuid& guid,
RequestingApplication requester) override;
private:
static const char* s_extension;
};
} // namespace FbxSceneImporter
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,437 @@
/*
* 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 <AzCore/Debug/Trace.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/containers/queue.h>
#include <AzCore/std/string/string.h>
#include <AzCore/std/string/conversions.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/FbxImporter.h>
#include <SceneAPI/FbxSceneBuilder/ImportContexts/FbxImportContexts.h>
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpMaterialImporter.h>
#endif
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.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>
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#endif
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
struct QueueNode
{
std::shared_ptr<SDKNode::NodeWrapper> m_node;
Containers::SceneGraph::NodeIndex m_parent;
QueueNode() = delete;
QueueNode(std::shared_ptr<SDKNode::NodeWrapper>&& node, Containers::SceneGraph::NodeIndex parent)
: m_node(std::move(node))
, m_parent(parent)
{
}
};
FbxImporter::FbxImporter()
: m_sceneSystem(new FbxSceneSystem())
{
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
if (m_useAssetImporterSDK)
{
m_sceneWrapper = AZStd::make_unique<AssImpSDKWrapper::AssImpSceneWrapper>();
}
else
{
m_sceneWrapper = AZStd::make_unique<FbxSDKWrapper::FbxSceneWrapper>();
}
#else
m_sceneWrapper = AZStd::make_unique<FbxSDKWrapper::FbxSceneWrapper>();
#endif
BindToCall(&FbxImporter::ImportProcessing);
}
void FbxImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult FbxImporter::ImportProcessing(Events::ImportEventContext& context)
{
m_sceneWrapper->Clear();
if (!m_sceneWrapper->LoadSceneFromFile(context.GetInputDirectory().c_str()))
{
return Events::ProcessingResult::Failure;
}
typedef AZStd::function<bool(Containers::Scene & scene)> ConvertFunc;
ConvertFunc convertFunc;
m_sceneSystem->Set(m_sceneWrapper.get());
if (azrtti_istypeof<FbxSDKWrapper::FbxSceneWrapper>(m_sceneWrapper.get()))
{
convertFunc = AZStd::bind(&FbxImporter::ConvertFbxSceneContext, this, AZStd::placeholders::_1);
}
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
else
{
convertFunc = AZStd::bind(&FbxImporter::ConvertFbxScene, this, AZStd::placeholders::_1);
}
#endif
if (convertFunc(context.GetScene()))
{
return Events::ProcessingResult::Success;
}
else
{
return Events::ProcessingResult::Failure;
}
}
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;
}
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
bool FbxImporter::ConvertFbxScene(Containers::Scene& scene) const
{
std::shared_ptr<SDKNode::NodeWrapper> fbxRoot = m_sceneWrapper->GetRootNode();
if (!fbxRoot)
{
return false;
}
const AssImpSDKWrapper::AssImpSceneWrapper* assImpSceneWrapper = azrtti_cast <AssImpSDKWrapper::AssImpSceneWrapper*>(m_sceneWrapper.get());
AZStd::pair<AssImpSDKWrapper::AssImpSceneWrapper::AxisVector, int32_t> upAxisAndSign = assImpSceneWrapper->GetUpVectorAndSign();
if (upAxisAndSign.second <= 0)
{
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Negative scene orientation is not a currently supported orientation.");
return false;
}
switch (upAxisAndSign.first)
{
case AssImpSDKWrapper::AssImpSceneWrapper::AxisVector::X:
scene.SetOriginalSceneOrientation(Containers::Scene::SceneOrientation::XUp);
break;
case AssImpSDKWrapper::AssImpSceneWrapper::AxisVector::Y:
scene.SetOriginalSceneOrientation(Containers::Scene::SceneOrientation::YUp);
break;
case AssImpSDKWrapper::AssImpSceneWrapper::AxisVector::Z:
scene.SetOriginalSceneOrientation(Containers::Scene::SceneOrientation::ZUp);
break;
default:
AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Unknown scene orientation, %d.", upAxisAndSign.first);
AZ_Assert(false, "Unknown scene orientation, %d.", upAxisAndSign.first);
break;
}
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 asset importer node queued");
if (!nodeNameMap.RegisterNode(node.m_node, scene.GetGraph(), node.m_parent))
{
AZ_TracePrintf(Utilities::ErrorWindow, "Failed to register asset importer 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_Error(Utilities::ErrorWindow, newNode.IsValid(), "Failed to add Asset Importer node to scene graph");
if (!newNode.IsValid())
{
continue;
}
AssImpNodeEncounteredContext sourceNodeEncountered(scene, newNode, *assImpSceneWrapper, *m_sceneSystem, nodeNameMap, *azrtti_cast<AZ::AssImpSDKWrapper::AssImpNodeWrapper*>(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.");
}
AssImpSceneDataPopulatedContext 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");
AssImpSceneDataPopulatedContext 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<AssImpSDKWrapper::AssImpNodeWrapper> child = std::make_shared<AssImpSDKWrapper::AssImpNodeWrapper>(node.m_node->GetChild(i)->GetAssImpNode());
if (child)
{
nodes.emplace(AZStd::move(child), newNode);
}
}
nodes.pop();
};
Events::ProcessingResult result = Events::Process<AssImpFinalizeSceneContext>(scene, *assImpSceneWrapper, *m_sceneSystem, nodeNameMap);
if (result == Events::ProcessingResult::Failure)
{
return false;
}
return true;
}
#endif
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,61 @@
/*
* 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/unique_ptr.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
#include <SceneAPI/SceneCore/Events/ImportEventContext.h>
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
#include <SceneAPI/SDKWrapper/SceneWrapper.h>
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
class Scene;
}
namespace FbxSceneBuilder
{
class FbxImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(FbxImporter, "{D5EE21B6-8B73-45BF-B711-31346E0BEDB3}", SceneCore::LoadingComponent);
FbxImporter();
~FbxImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportProcessing(Events::ImportEventContext& context);
protected:
bool ConvertFbxSceneContext(Containers::Scene& scene) const;
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
bool ConvertFbxScene(Containers::Scene& scene) const;
#endif
AZStd::unique_ptr<SDKScene::SceneWrapperBase> m_sceneWrapper;
AZStd::shared_ptr<FbxSceneSystem> m_sceneSystem;
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
bool m_useAssetImporterSDK = false;
#endif
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,25 @@
#pragma once
/*
* 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/PlatformDef.h>
#if defined(AZ_MONOLITHIC_BUILD)
#define FBX_SCENE_BUILDER_API
#else
#ifdef FBX_SCENE_BUILDER_EXPORTS
#define FBX_SCENE_BUILDER_API AZ_DLL_EXPORT
#else
#define FBX_SCENE_BUILDER_API AZ_DLL_IMPORT
#endif
#endif // AZ_MONOLITHIC_BUILD
@@ -0,0 +1,180 @@
/*
* 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/Math/Vector3.h>
#include <SceneAPI/FbxSDKWrapper/FbxSceneWrapper.h>
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
#include <assimp/scene.h>
#endif
namespace AZ
{
namespace SceneAPI
{
FbxSceneSystem::FbxSceneSystem() :
m_unitSizeInMeters(1.0f),
m_originalUnitSizeInMeters(1.0f),
m_adjustTransform(nullptr),
m_adjustTransformInverse(nullptr)
{
}
void FbxSceneSystem::Set(const SDKScene::SceneWrapperBase* fbxScene)
{
// Get unit conversion factor to meter.
if (azrtti_istypeof<FbxSDKWrapper::FbxSceneWrapper>(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()));
}
}
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
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)
{
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)
{
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));
}
}
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()));
}
}
#endif
}
void FbxSceneSystem::SwapVec3ForUpAxis(Vector3& swapVector) const
{
if (m_adjustTransform)
{
swapVector = *m_adjustTransform * swapVector;
}
}
void FbxSceneSystem::SwapTransformForUpAxis(DataTypes::MatrixType& inOutTransform) const
{
if (m_adjustTransform)
{
inOutTransform = (*m_adjustTransform * inOutTransform) * *m_adjustTransformInverse;
}
}
void FbxSceneSystem::ConvertUnit(Vector3& scaleVector) const
{
scaleVector *= m_unitSizeInMeters;
}
void FbxSceneSystem::ConvertUnit(DataTypes::MatrixType& inOutTransform) const
{
Vector3 translation = inOutTransform.GetTranslation();
translation *= m_unitSizeInMeters;
inOutTransform.SetTranslation(translation);
}
void FbxSceneSystem::ConvertBoneUnit(DataTypes::MatrixType& inOutTransform) const
{
// Need to scale translation explicitly as MultiplyByScale won't change the translation component
// and we need to convert to meter unit
Vector3 translation = inOutTransform.GetTranslation();
translation *= m_unitSizeInMeters;
inOutTransform.SetTranslation(translation);
}
}
}
@@ -0,0 +1,61 @@
#pragma once
/*
* 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/std/smart_ptr/unique_ptr.h>
#include <SceneAPI/FbxSceneBuilder/FbxSceneBuilderConfiguration.h>
#include <SceneAPI/SceneCore/DataTypes/MatrixType.h>
namespace AZ
{
class Vector3;
namespace SDKScene
{
class SceneWrapperBase;
}
namespace SceneAPI
{
class FBX_SCENE_BUILDER_API FbxSceneSystem
{
public:
FbxSceneSystem();
void Set(const SDKScene::SceneWrapperBase* sceneWrapper);
void SwapVec3ForUpAxis(Vector3& swapVector) const;
void SwapTransformForUpAxis(DataTypes::MatrixType& inOutTransform) const;
void ConvertUnit(Vector3& scaleVector) const;
void ConvertUnit(DataTypes::MatrixType& inOutTransform) const;
void ConvertBoneUnit(DataTypes::MatrixType& inOutTransform) const;
//! Get effect unit size in meters of this Fbx Scene, internally FBX saves it in the following manner
//! GlobalSettings: {
//! P : "UnitScaleFactor", "double", "Number", "", 2.54
float GetUnitSizeInMeters() const { return m_unitSizeInMeters; }
//! Get original unit size in meters of this Fbx Scene, internally FBX saves it in the following manner
//! GlobalSettings: {
//! P : "OriginalUnitScaleFactor", "double", "Number", "", 2.54
float GetOriginalUnitSizeInMeters() const { return m_originalUnitSizeInMeters; }
protected:
float m_unitSizeInMeters = 1;
float m_originalUnitSizeInMeters = 1;
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
AZStd::unique_ptr<DataTypes::MatrixType> m_adjustTransform;
AZStd::unique_ptr<DataTypes::MatrixType> m_adjustTransformInverse;
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
};
}
};
@@ -0,0 +1,129 @@
/*
* 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/AssImpImportContexts.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SceneCore/Events/ImportEventContext.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
AssImpImportContext::AssImpImportContext(const AssImpSDKWrapper::AssImpSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem,
AssImpSDKWrapper::AssImpNodeWrapper& sourceNode)
: m_sourceScene(sourceScene)
, m_sourceSceneSystem(sourceSceneSystem)
, m_sourceNode(sourceNode)
{
}
AssImpNodeEncounteredContext::AssImpNodeEncounteredContext(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition,
const AssImpSDKWrapper::AssImpSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem,
RenamedNodesMap& nodeNameMap,
AssImpSDKWrapper::AssImpNodeWrapper& sourceNode)
: AssImpImportContext(sourceScene, sourceSceneSystem, sourceNode)
, NodeEncounteredContext(scene, currentGraphPosition, nodeNameMap)
{
}
AssImpNodeEncounteredContext::AssImpNodeEncounteredContext(
Events::ImportEventContext& parent,
Containers::SceneGraph::NodeIndex currentGraphPosition,
const AssImpSDKWrapper::AssImpSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem,
RenamedNodesMap& nodeNameMap,
AssImpSDKWrapper::AssImpNodeWrapper& sourceNode)
: AssImpImportContext(sourceScene, sourceSceneSystem, sourceNode)
, NodeEncounteredContext(parent.GetScene(), currentGraphPosition, nodeNameMap)
{
}
AssImpSceneDataPopulatedContext::AssImpSceneDataPopulatedContext(AssImpNodeEncounteredContext& parent,
const AZStd::shared_ptr<DataTypes::IGraphObject>& graphData, const AZStd::string& dataName)
: AssImpImportContext(parent.m_sourceScene, parent.m_sourceSceneSystem, parent.m_sourceNode)
, SceneDataPopulatedContextBase(parent, graphData, dataName)
{
}
AssImpSceneDataPopulatedContext::AssImpSceneDataPopulatedContext(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition,
const AssImpSDKWrapper::AssImpSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem,
RenamedNodesMap& nodeNameMap,
AssImpSDKWrapper::AssImpNodeWrapper& sourceNode,
const AZStd::shared_ptr<DataTypes::IGraphObject>& nodeData, const AZStd::string& dataName)
: AssImpImportContext(sourceScene, sourceSceneSystem, sourceNode)
, SceneDataPopulatedContextBase(scene, currentGraphPosition, nodeNameMap, nodeData, dataName)
{
}
AssImpSceneNodeAppendedContext::AssImpSceneNodeAppendedContext(AssImpSceneDataPopulatedContext& parent,
Containers::SceneGraph::NodeIndex newIndex)
: AssImpImportContext(parent.m_sourceScene, parent.m_sourceSceneSystem, parent.m_sourceNode)
, SceneNodeAppendedContextBase(parent.m_scene, newIndex, parent.m_nodeNameMap)
{
}
AssImpSceneNodeAppendedContext::AssImpSceneNodeAppendedContext(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition,
const AssImpSDKWrapper::AssImpSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem,
RenamedNodesMap& nodeNameMap, AssImpSDKWrapper::AssImpNodeWrapper& sourceNode)
: AssImpImportContext(sourceScene, sourceSceneSystem, sourceNode)
, SceneNodeAppendedContextBase(scene, currentGraphPosition, nodeNameMap)
{
}
AssImpSceneAttributeDataPopulatedContext::AssImpSceneAttributeDataPopulatedContext(AssImpSceneNodeAppendedContext& parent, const AZStd::shared_ptr<DataTypes::IGraphObject>& nodeData, const Containers::SceneGraph::NodeIndex attributeNodeIndex, const AZStd::string& dataName)
: AssImpImportContext(parent.m_sourceScene, parent.m_sourceSceneSystem, parent.m_sourceNode)
, SceneAttributeDataPopulatedContextBase(parent, nodeData, attributeNodeIndex, dataName)
{
}
AssImpSceneAttributeNodeAppendedContext::AssImpSceneAttributeNodeAppendedContext(AssImpSceneAttributeDataPopulatedContext& parent, Containers::SceneGraph::NodeIndex newIndex)
: AssImpImportContext(parent.m_sourceScene, parent.m_sourceSceneSystem, parent.m_sourceNode)
, SceneAttributeNodeAppendedContextBase(parent, newIndex)
{
}
AssImpSceneNodeAddedAttributesContext::AssImpSceneNodeAddedAttributesContext(AssImpSceneNodeAppendedContext& parent)
: AssImpImportContext(parent.m_sourceScene, parent.m_sourceSceneSystem, parent.m_sourceNode)
, SceneNodeAddedAttributesContextBase(parent)
{
}
AssImpSceneNodeFinalizeContext::AssImpSceneNodeFinalizeContext(AssImpSceneNodeAddedAttributesContext& parent)
: AssImpImportContext(parent.m_sourceScene, parent.m_sourceSceneSystem, parent.m_sourceNode)
, SceneNodeFinalizeContextBase(parent)
{
}
AssImpFinalizeSceneContext::AssImpFinalizeSceneContext(Containers::Scene& scene,
const AssImpSDKWrapper::AssImpSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem,
RenamedNodesMap& nodeNameMap)
: FinalizeSceneContextBase(scene, nodeNameMap)
, m_sourceScene(sourceScene)
, m_sourceSceneSystem(sourceSceneSystem)
{
}
} // namespace SceneAPI
} // namespace FbxSceneBuilder
} // namespace AZ
@@ -0,0 +1,187 @@
/*
* 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 AssImpSDKWrapper
{
class AssImpNodeWrapper;
class AssImpSceneWrapper;
}
namespace SceneAPI
{
class FbxSceneSystem;
namespace FbxSceneBuilder
{
class RenamedNodesMap;
// AssImpImportContext
// Base structure containing common data needed for all import contexts
// Member Variables:
// m_sourceNode - AssImp node being used for data processing.
struct AssImpImportContext
{
AZ_RTTI(AssImpImportContext, "{B1076AFF-991B-423C-8D3E-D5C9230434AB}");
AssImpImportContext(const AssImpSDKWrapper::AssImpSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem,
AssImpSDKWrapper::AssImpNodeWrapper& sourceNode);
const AssImpSDKWrapper::AssImpSceneWrapper& m_sourceScene;
AssImpSDKWrapper::AssImpNodeWrapper& m_sourceNode;
const FbxSceneSystem& m_sourceSceneSystem; // Needed for unit and axis conversion
};
// AssImpNodeEncounteredContext
// Context pushed to indicate that a new AssImp Node has been found and any
// importers that have means to process the contained data should do so
struct AssImpNodeEncounteredContext
: public AssImpImportContext
, public NodeEncounteredContext
{
AZ_RTTI(AssImpNodeEncounteredContext, "{C2305BC5-EAEC-4515-BAD6-45E63C3FBD3D}", AssImpImportContext, NodeEncounteredContext);
AssImpNodeEncounteredContext(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition,
const AssImpSDKWrapper::AssImpSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem,
RenamedNodesMap& nodeNameMap,
AssImpSDKWrapper::AssImpNodeWrapper& sourceNode);
AssImpNodeEncounteredContext(Events::ImportEventContext& parent,
Containers::SceneGraph::NodeIndex currentGraphPosition,
const AssImpSDKWrapper::AssImpSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem,
RenamedNodesMap& nodeNameMap,
AssImpSDKWrapper::AssImpNodeWrapper& sourceNode);
};
// AssImpSceneDataPopulatedContext
// 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.
struct AssImpSceneDataPopulatedContext
: public AssImpImportContext
, public SceneDataPopulatedContextBase
{
AZ_RTTI(AssImpSceneDataPopulatedContext, "{888DA37E-4234-4990-AD50-E6E54AFA9C35}", AssImpImportContext, SceneDataPopulatedContextBase);
AssImpSceneDataPopulatedContext(AssImpNodeEncounteredContext& parent,
const AZStd::shared_ptr<DataTypes::IGraphObject>& nodeData,
const AZStd::string& dataName);
AssImpSceneDataPopulatedContext(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition,
const AssImpSDKWrapper::AssImpSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem,
RenamedNodesMap& nodeNameMap,
AssImpSDKWrapper::AssImpNodeWrapper& sourceNode,
const AZStd::shared_ptr<DataTypes::IGraphObject>& nodeData,
const AZStd::string& dataName);
};
// AssImpSceneNodeAppendedContext
// 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 AssImpSceneNodeAppendedContext
: public AssImpImportContext
, public SceneNodeAppendedContextBase
{
AZ_RTTI(AssImpSceneNodeAppendedContext, "{9C8B688E-8ECD-4EF0-9AC6-21BBCFE8F5A3}", AssImpImportContext, SceneNodeAppendedContextBase);
AssImpSceneNodeAppendedContext(AssImpSceneDataPopulatedContext& parent, Containers::SceneGraph::NodeIndex newIndex);
AssImpSceneNodeAppendedContext(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition,
const AssImpSDKWrapper::AssImpSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem,
RenamedNodesMap& nodeNameMap,
AssImpSDKWrapper::AssImpNodeWrapper& sourceNode);
};
// AssImpSceneAttributeDataPopulatedContext
// Context pushed to indicate that attribute data has been found and processed
struct AssImpSceneAttributeDataPopulatedContext
: public AssImpImportContext
, public SceneAttributeDataPopulatedContextBase
{
AZ_RTTI(AssImpSceneAttributeDataPopulatedContext, "{A5EFB485-2F36-4214-972B-0EFF4EFBF33D}", AssImpImportContext, SceneAttributeDataPopulatedContextBase);
AssImpSceneAttributeDataPopulatedContext(AssImpSceneNodeAppendedContext& parent,
const AZStd::shared_ptr<DataTypes::IGraphObject>& nodeData,
const Containers::SceneGraph::NodeIndex attributeNodeIndex,const AZStd::string& dataName);
};
// AssImpSceneAttributeNodeAppendedContext
// Context pushed to indicate that an attribute node has been added to the scene graph
struct AssImpSceneAttributeNodeAppendedContext
: public AssImpImportContext
, public SceneAttributeNodeAppendedContextBase
{
AZ_RTTI(AssImpSceneAttributeNodeAppendedContext, "{96FDC405-2D3B-4030-A301-B3A2B5432498}", AssImpImportContext, SceneAttributeNodeAppendedContextBase);
AssImpSceneAttributeNodeAppendedContext(AssImpSceneAttributeDataPopulatedContext& parent, Containers::SceneGraph::NodeIndex newIndex);
};
// AssImpSceneNodeAddedAttributesContext
// Context pushed to indicate that all attribute processors have completed their
// work for a specific data node.
struct AssImpSceneNodeAddedAttributesContext
: public AssImpImportContext
, public SceneNodeAddedAttributesContextBase
{
AZ_RTTI(AssImpSceneNodeAddedAttributesContext, "{D305EAA5-5F16-4AAD-805D-DF07A1B355B9}", AssImpImportContext, SceneNodeAddedAttributesContextBase);
AssImpSceneNodeAddedAttributesContext(AssImpSceneNodeAppendedContext& parent);
};
// AssImpSceneNodeFinalizeContext
// Context pushed last after all other contexts for a scene node to allow any
// post-processing needed for an importer.
struct AssImpSceneNodeFinalizeContext
: public AssImpImportContext
, public SceneNodeFinalizeContextBase
{
AZ_RTTI(AssImpSceneNodeFinalizeContext, "{FD8B4AD5-3735-4D55-9455-504AB1DCA655}", AssImpImportContext, SceneNodeFinalizeContextBase);
AssImpSceneNodeFinalizeContext(AssImpSceneNodeAddedAttributesContext& parent);
};
// AssImpFinalizeSceneContext
// Context pushed after the scene has been fully created. This can be used to finalize pending work
// such as resolving named links.
struct AssImpFinalizeSceneContext
: public FinalizeSceneContextBase
{
AZ_RTTI(AssImpFinalizeSceneContext, "{6B23A54A-44BF-4661-A130-6B4D06A57B9F}", FinalizeSceneContextBase);
AssImpFinalizeSceneContext(
Containers::Scene& scene,
const AssImpSDKWrapper::AssImpSceneWrapper& sourceScene,
const FbxSceneSystem& sourceSceneSystem,
RenamedNodesMap& nodeNameMap);
const AssImpSDKWrapper::AssImpSceneWrapper& m_sourceScene;
const FbxSceneSystem& m_sourceSceneSystem; // Needed for unit and axis conversion
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,115 @@
/*
* 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
@@ -0,0 +1,184 @@
/*
* 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
@@ -0,0 +1,112 @@
/*
* 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/ImportContexts.h>
#include <SceneAPI/SceneCore/Events/ImportEventContext.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
ImportContext::ImportContext(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition,
RenamedNodesMap& nodeNameMap)
: m_scene(scene)
, m_currentGraphPosition(currentGraphPosition)
, m_nodeNameMap(nodeNameMap)
{
}
ImportContext::ImportContext(Containers::Scene& scene, RenamedNodesMap& nodeNameMap)
: m_scene(scene)
, m_nodeNameMap(nodeNameMap)
{
m_currentGraphPosition = Containers::SceneGraph::NodeIndex();
}
NodeEncounteredContext::NodeEncounteredContext(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition,
RenamedNodesMap& nodeNameMap)
: ImportContext(scene, currentGraphPosition, nodeNameMap)
{
}
NodeEncounteredContext::NodeEncounteredContext(
Events::ImportEventContext& parent, Containers::SceneGraph::NodeIndex currentGraphPosition,
RenamedNodesMap& nodeNameMap)
: ImportContext(parent.GetScene(), currentGraphPosition, nodeNameMap)
{
}
SceneDataPopulatedContextBase::SceneDataPopulatedContextBase(NodeEncounteredContext& parent,
const AZStd::shared_ptr<DataTypes::IGraphObject>& graphData, const AZStd::string& dataName)
: ImportContext(parent.m_scene, parent.m_currentGraphPosition, parent.m_nodeNameMap)
, m_graphData(graphData)
, m_dataName(dataName)
{
}
SceneDataPopulatedContextBase::SceneDataPopulatedContextBase(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition,
RenamedNodesMap& nodeNameMap,
const AZStd::shared_ptr<DataTypes::IGraphObject>& nodeData, const AZStd::string& dataName)
: ImportContext(scene, currentGraphPosition, nodeNameMap)
, m_graphData(nodeData)
, m_dataName(dataName)
{
}
SceneNodeAppendedContextBase::SceneNodeAppendedContextBase(SceneDataPopulatedContextBase& parent,
Containers::SceneGraph::NodeIndex newIndex)
: ImportContext(parent.m_scene, newIndex, parent.m_nodeNameMap)
{
}
SceneNodeAppendedContextBase::SceneNodeAppendedContextBase(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition, RenamedNodesMap& nodeNameMap)
: ImportContext(scene, currentGraphPosition, nodeNameMap)
{
}
SceneAttributeDataPopulatedContextBase::SceneAttributeDataPopulatedContextBase(SceneNodeAppendedContextBase& parent,
const AZStd::shared_ptr<DataTypes::IGraphObject>& nodeData,
const Containers::SceneGraph::NodeIndex attributeNodeIndex, const AZStd::string& dataName)
: ImportContext(parent.m_scene, attributeNodeIndex, parent.m_nodeNameMap)
, m_graphData(nodeData)
, m_dataName(dataName)
{
}
SceneAttributeNodeAppendedContextBase::SceneAttributeNodeAppendedContextBase(SceneAttributeDataPopulatedContextBase& parent, Containers::SceneGraph::NodeIndex newIndex)
: ImportContext(parent.m_scene, newIndex, parent.m_nodeNameMap)
{
}
SceneNodeAddedAttributesContextBase::SceneNodeAddedAttributesContextBase(SceneNodeAppendedContextBase& parent)
: ImportContext(parent.m_scene, parent.m_currentGraphPosition, parent.m_nodeNameMap)
{
}
SceneNodeFinalizeContextBase::SceneNodeFinalizeContextBase(SceneNodeAddedAttributesContextBase& parent)
: ImportContext(parent.m_scene, parent.m_currentGraphPosition, parent.m_nodeNameMap)
{
}
FinalizeSceneContextBase::FinalizeSceneContextBase(Containers::Scene& scene, RenamedNodesMap& nodeNameMap)
: ImportContext(scene, nodeNameMap)
{
}
} // namespace SceneAPI
} // namespace FbxSceneBuilder
} // namespace AZ
@@ -0,0 +1,184 @@
/*
* 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/SceneCore/Events/CallProcessorBus.h>
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
namespace AZ
{
namespace SceneAPI
{
namespace Containers
{
class Scene;
}
namespace DataTypes
{
class IGraphObject;
}
namespace Events
{
class ImportEventContext;
}
namespace FbxSceneBuilder
{
class RenamedNodesMap;
// ImportContext
// Base structure containing common data needed for all import contexts
struct ImportContext
: public Events::ICallContext
{
AZ_RTTI(ImportContext, "{68E546D5-9B79-4293-AD37-4A4BA688892F}", Events::ICallContext);
ImportContext(Containers::Scene& scene, Containers::SceneGraph::NodeIndex currentGraphPosition,
RenamedNodesMap& nodeNameMap);
ImportContext(Containers::Scene& scene, RenamedNodesMap& nodeNameMap);
Containers::Scene& m_scene;
Containers::SceneGraph::NodeIndex m_currentGraphPosition;
RenamedNodesMap& m_nodeNameMap; // Map of the nodes that have received a new name.
};
// NodeEncounteredContext
// Context pushed to indicate that a new 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 NodeEncounteredContext
: public ImportContext
{
AZ_RTTI(NodeEncounteredContext, "{40C31D76-7101-4ACD-8849-0D6D0AF62855}", ImportContext);
NodeEncounteredContext(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition,
RenamedNodesMap& nodeNameMap);
NodeEncounteredContext(Events::ImportEventContext& parent,
Containers::SceneGraph::NodeIndex currentGraphPosition,
RenamedNodesMap& nodeNameMap);
AZStd::vector<AZStd::shared_ptr<DataTypes::IGraphObject>> m_createdData;
};
// SceneDataPopulatedContextBase
// 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.
// 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
struct SceneDataPopulatedContextBase
: public ImportContext
{
AZ_RTTI(SceneDataPopulatedContextBase, "{5F4CE8D2-EEAC-49F7-8065-0B6372162D6F}", ImportContext);
SceneDataPopulatedContextBase(NodeEncounteredContext& parent,
const AZStd::shared_ptr<DataTypes::IGraphObject>& nodeData,
const AZStd::string& dataName);
SceneDataPopulatedContextBase(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition,
RenamedNodesMap& nodeNameMap,
const AZStd::shared_ptr<DataTypes::IGraphObject>& nodeData, const AZStd::string& dataName);
const AZStd::shared_ptr<DataTypes::IGraphObject>& m_graphData;
const AZStd::string m_dataName;
};
// SceneNodeAppendedContextBase
// Context pushed to indicate that data has been added to the scene graph.
// Generally created due to the insertion of a node during SceneDataPopulatedContextBase
// processing.
struct SceneNodeAppendedContextBase
: public ImportContext
{
AZ_RTTI(SceneNodeAppendedContextBase, "{0A69FB6C-2B1B-46E7-AEC3-C4B8ABBFDD69}", ImportContext);
SceneNodeAppendedContextBase(SceneDataPopulatedContextBase& parent, Containers::SceneGraph::NodeIndex newIndex);
SceneNodeAppendedContextBase(Containers::Scene& scene,
Containers::SceneGraph::NodeIndex currentGraphPosition, RenamedNodesMap& nodeNameMap);
};
// SceneAttributeDataPopulatedContextBase
// Context pushed to indicate that attribute data has been found and processed
struct SceneAttributeDataPopulatedContextBase
: public ImportContext
{
AZ_RTTI(SceneAttributeDataPopulatedContextBase, "{DA133E14-0770-435B-9A4E-38679367F56C}", ImportContext);
SceneAttributeDataPopulatedContextBase(SceneNodeAppendedContextBase& parent,
const AZStd::shared_ptr<DataTypes::IGraphObject>& nodeData,
const Containers::SceneGraph::NodeIndex attributeNodeIndex, const AZStd::string& dataName);
const AZStd::shared_ptr<DataTypes::IGraphObject>& m_graphData;
const AZStd::string m_dataName;
};
// SceneAttributeNodeAppendedContextBase
// Context pushed to indicate that an attribute node has been added to the scene graph
struct SceneAttributeNodeAppendedContextBase
: public ImportContext
{
AZ_RTTI(SceneAttributeNodeAppendedContextBase, "{8A382A1E-CFE7-47D2-BA5B-CFDF1FB9F03D}", ImportContext);
SceneAttributeNodeAppendedContextBase(SceneAttributeDataPopulatedContextBase& parent,
Containers::SceneGraph::NodeIndex newIndex);
};
// SceneNodeAddedAttributesContextBase
// Context pushed to indicate that all attribute processors have completed their
// work for a specific data node.
struct SceneNodeAddedAttributesContextBase
: public ImportContext
{
AZ_RTTI(SceneNodeAddedAttributesContextBase, "{65B97E48-16A0-4BBD-B364-CFDA9E3600B6}", ImportContext);
SceneNodeAddedAttributesContextBase(SceneNodeAppendedContextBase& parent);
};
// SceneNodeFinalizeContextBase
// Context pushed last after all other contexts for a scene node to allow any
// post-processing needed for an importer.
struct SceneNodeFinalizeContextBase
: public ImportContext
{
AZ_RTTI(SceneNodeFinalizeContextBase, "{F2C7D1BC-8065-423E-9212-241EB426A2BB}", ImportContext);
SceneNodeFinalizeContextBase(SceneNodeAddedAttributesContextBase& parent);
};
// FinalizeSceneContextBase
// Context pushed after the scene has been fully created. This can be used to finalize pending work
// such as resolving named links.
struct FinalizeSceneContextBase
: public ImportContext
{
AZ_RTTI(FinalizeSceneContextBase, "{91C54F51-9B4D-4C61-956C-9D530725D737}", ImportContext);
FinalizeSceneContextBase(Containers::Scene& scene, RenamedNodesMap& nodeNameMap);
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,119 @@
/*
* 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/AssImpColorStreamImporter.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.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 <assimp/scene.h>
#include <assimp/mesh.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
const char* AssImpColorStreamImporter::m_defaultNodeName = "Col";
AssImpColorStreamImporter::AssImpColorStreamImporter()
{
BindToCall(&AssImpColorStreamImporter::ImportColorStreams);
}
void AssImpColorStreamImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpColorStreamImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult AssImpColorStreamImporter::ImportColorStreams(AssImpSceneNodeAppendedContext& context)
{
AZ_TraceContext("Importer", m_defaultNodeName);
if (!context.m_sourceNode.ContainsMesh())
{
return Events::ProcessingResult::Ignored;
}
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
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()))
{
return Events::ProcessingResult::Failure;
}
const SceneData::GraphData::MeshData* const parentMeshData = azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
size_t vertexCount = parentMeshData->GetVertexCount();
int sdkMeshIndex = parentMeshData->GetSdkMeshIndex();
if (sdkMeshIndex < 0)
{
AZ_Error(
Utilities::ErrorWindow,
false,
"Tried to construct color stream attribute for invalid or non-mesh parent data, mesh index is missing");
return Events::ProcessingResult::Failure;
}
aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[sdkMeshIndex]];
Events::ProcessingResultCombiner combinedVertexColorResults;
for (int colorSetIndex = 0; colorSetIndex < mesh->GetNumColorChannels(); ++colorSetIndex)
{
AZStd::shared_ptr<SceneData::GraphData::MeshVertexColorData> vertexColors =
AZStd::make_shared<AZ::SceneData::GraphData::MeshVertexColorData>();
vertexColors->ReserveContainerSpace(vertexCount);
for (int v = 0; v < mesh->mNumVertices; ++v)
{
AZ::SceneAPI::DataTypes::Color vertexColor(
AssImpSDKWrapper::AssImpTypeConverter::ToColor(mesh->mColors[colorSetIndex][v]));
vertexColors->AppendColor(vertexColor);
}
AZStd::string nodeName(AZStd::string::format("%s%d",m_defaultNodeName,colorSetIndex));
Containers::SceneGraph::NodeIndex newIndex =
context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, nodeName.c_str());
Events::ProcessingResult colorMapResults;
AssImpSceneAttributeDataPopulatedContext dataPopulated(context, vertexColors, newIndex, nodeName.c_str());
colorMapResults = Events::Process(dataPopulated);
if (colorMapResults != Events::ProcessingResult::Failure)
{
colorMapResults = AddAttributeDataNodeWithContexts(dataPopulated);
}
combinedVertexColorResults += colorMapResults;
}
return combinedVertexColorResults.GetResult();
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,40 @@
/*
* 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/AssImpImportContexts.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
class AssImpColorStreamImporter : public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(AssImpColorStreamImporter, "{071F4764-F3B0-438A-9CB7-19A1248F3B54}", SceneCore::LoadingComponent);
AssImpColorStreamImporter();
~AssImpColorStreamImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportColorStreams(AssImpSceneNodeAppendedContext& context);
protected:
static const char* m_defaultNodeName;
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,140 @@
/*
* 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/Importers/AssImpMaterialImporter.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpMaterialWrapper.h>
#include <SceneAPI/SceneData/GraphData/MaterialData.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneCore/Events/ProcessingResult.h>
#include <assimp/scene.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
AssImpMaterialImporter::AssImpMaterialImporter()
{
BindToCall(&AssImpMaterialImporter::ImportMaterials);
}
void AssImpMaterialImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpMaterialImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult AssImpMaterialImporter::ImportMaterials(AssImpSceneNodeAppendedContext& context)
{
AZ_TraceContext("Importer", "Material");
if (!context.m_sourceNode.ContainsMesh())
{
return Events::ProcessingResult::Ignored;
}
Events::ProcessingResultCombiner combinedMaterialImportResults;
for (int idx = 0; idx < context.m_sourceNode.m_assImpNode->mNumMeshes; ++idx)
{
int meshIndex = context.m_sourceNode.m_assImpNode->mMeshes[idx];
aiMesh* assImpMesh = context.m_sourceScene.GetAssImpScene()->mMeshes[meshIndex];
AZ_Assert(assImpMesh, "Asset Importer Mesh should not be null.");
int materialIndex = assImpMesh->mMaterialIndex;
AZ_TraceContext("Material Index", materialIndex);
AZStd::unordered_map<int, AZStd::shared_ptr<SceneData::GraphData::MaterialData>> materialMap;
auto matFound = materialMap.find(materialIndex);
AZStd::shared_ptr<SceneData::GraphData::MaterialData> material;
AZStd::string materialName;
if (matFound == materialMap.end())
{
std::shared_ptr<AssImpSDKWrapper::AssImpMaterialWrapper> assImpMaterial =
std::shared_ptr<AssImpSDKWrapper::AssImpMaterialWrapper>(new AssImpSDKWrapper::AssImpMaterialWrapper(context.m_sourceScene.GetAssImpScene()->mMaterials[materialIndex]));
materialName = assImpMaterial->GetName().c_str();
RenamedNodesMap::SanitizeNodeName(materialName, context.m_scene.GetGraph(), context.m_currentGraphPosition, "Material");
AZ_TraceContext("Material Name", materialName);
material = AZStd::make_shared<SceneData::GraphData::MaterialData>();
material->SetMaterialName(assImpMaterial->GetName());
material->SetTexture(DataTypes::IMaterialData::TextureMapType::Diffuse,
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::Diffuse).c_str());
material->SetTexture(DataTypes::IMaterialData::TextureMapType::Specular,
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::Specular).c_str());
material->SetTexture(DataTypes::IMaterialData::TextureMapType::Bump,
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::Bump).c_str());
material->SetTexture(DataTypes::IMaterialData::TextureMapType::Normal,
assImpMaterial->GetTextureFileName(SDKMaterial::MaterialWrapper::MaterialMapType::Normal).c_str());
material->SetUniqueId(assImpMaterial->GetUniqueId());
material->SetDiffuseColor(assImpMaterial->GetDiffuseColor());
material->SetSpecularColor(assImpMaterial->GetSpecularColor());
material->SetEmissiveColor(assImpMaterial->GetEmissiveColor());
material->SetShininess(assImpMaterial->GetShininess());
AZ_Assert(material, "Failed to allocate scene material data.");
if (!material)
{
combinedMaterialImportResults += Events::ProcessingResult::Failure;
continue;
}
materialMap[materialIndex] = material;
}
else
{
material = matFound->second;
materialName = material.get()->GetMaterialName();
}
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;
}
AssImpSceneAttributeDataPopulatedContext dataPopulated(context, material, newIndex, materialName);
materialResult = Events::Process(dataPopulated);
if (materialResult != Events::ProcessingResult::Failure)
{
materialResult = SceneAPI::FbxSceneBuilder::AddAttributeDataNodeWithContexts(dataPopulated);
}
combinedMaterialImportResults += materialResult;
}
return combinedMaterialImportResults.GetResult();
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,39 @@
/*
* 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/AssImpImportContexts.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
class AssImpMaterialImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(AssImpMaterialImporter, "{CD936FA9-17B8-40B9-AA3C-5F593BEFFC94}", SceneCore::LoadingComponent);
AssImpMaterialImporter();
~AssImpMaterialImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportMaterials(AssImpSceneNodeAppendedContext& context);
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,126 @@
/*
* 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/Importers/AssImpMeshImporter.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
#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/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <assimp/scene.h>
#include <assimp/mesh.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
AssImpMeshImporter::AssImpMeshImporter()
{
BindToCall(&AssImpMeshImporter::ImportMesh);
}
void AssImpMeshImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpMeshImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult AssImpMeshImporter::ImportMesh(AssImpNodeEncounteredContext& context)
{
AZ_TraceContext("Importer", "Mesh");
if (!context.m_sourceNode.ContainsMesh())
{
return Events::ProcessingResult::Ignored;
}
AZStd::unordered_map<int, int> assImpMatIndexToLYIndex;
int lyMeshIndex = 0;
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
for (int m = 0; m < currentNode->mNumMeshes; ++m)
{
AZStd::shared_ptr<SceneData::GraphData::MeshData> newMesh =
AZStd::make_shared<SceneData::GraphData::MeshData>();
newMesh->SetUnitSizeInMeters(context.m_sourceSceneSystem.GetUnitSizeInMeters());
newMesh->SetOriginalUnitSizeInMeters(context.m_sourceSceneSystem.GetOriginalUnitSizeInMeters());
newMesh->SetSdkMeshIndex(m);
aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[m]];
// Lumberyard materials are created in order based on mesh references in the scene
if (assImpMatIndexToLYIndex.find(mesh->mMaterialIndex) == assImpMatIndexToLYIndex.end())
{
assImpMatIndexToLYIndex.insert(AZStd::pair<int, int>(mesh->mMaterialIndex, lyMeshIndex++));
}
for (int vertIdx = 0; vertIdx < mesh->mNumVertices; ++vertIdx)
{
AZ::Vector3 vertex(
mesh->mVertices[vertIdx].x,
mesh->mVertices[vertIdx].y,
mesh->mVertices[vertIdx].z);
context.m_sourceSceneSystem.SwapVec3ForUpAxis(vertex);
context.m_sourceSceneSystem.ConvertUnit(vertex);
newMesh->AddPosition(vertex);
if (mesh->HasNormals())
{
AZ::Vector3 normal(
mesh->mNormals[vertIdx].x,
mesh->mNormals[vertIdx].y,
mesh->mNormals[vertIdx].z);
context.m_sourceSceneSystem.SwapVec3ForUpAxis(normal);
normal.NormalizeSafe();
newMesh->AddNormal(normal);
}
}
for (int faceIdx = 0; faceIdx < mesh->mNumFaces; ++faceIdx)
{
aiFace face = mesh->mFaces[faceIdx];
AZ::SceneAPI::DataTypes::IMeshData::Face meshFace;
if (face.mNumIndices != 3)
{
// AssImp should have triangulated everything, so if this happens then someone has
// probably changed AssImp's import settings. The engine only supports triangles.
AZ_Error(Utilities::ErrorWindow, false, "Mesh has a face with %d vertices, only 3 vertices are supported per face.");
continue;
}
for (int idx = 0; idx < face.mNumIndices; ++idx)
{
meshFace.vertexIndex[idx] = face.mIndices[idx];
}
newMesh->AddFace(meshFace, assImpMatIndexToLYIndex[mesh->mMaterialIndex]);
}
context.m_createdData.push_back(std::move(newMesh));
}
return Events::ProcessingResult::Success;
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,39 @@
/*
* 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/AssImpImportContexts.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
class AssImpMeshImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(AssImpMeshImporter, "{41611339-1D32-474A-A6A4-25CE4430AAFB}", SceneCore::LoadingComponent);
AssImpMeshImporter();
~AssImpMeshImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportMesh(AssImpNodeEncounteredContext& context);
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,111 @@
/*
* 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/Importers/AssImpTransformImporter.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#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/Utilities/RenamedNodesMap.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneData/GraphData/TransformData.h>
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
#include <assimp/scene.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
const char* AssImpTransformImporter::s_transformNodeName = "transform";
AssImpTransformImporter::AssImpTransformImporter()
{
BindToCall(&AssImpTransformImporter::ImportTransform);
}
void AssImpTransformImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpTransformImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult AssImpTransformImporter::ImportTransform(AssImpSceneNodeAppendedContext& context)
{
AZ_TraceContext("Importer", "transform");
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
DataTypes::MatrixType localTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(context.m_sourceNode.GetAssImpNode()->mTransformation);
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_Error(SceneAPI::Utilities::ErrorWindow, 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_Error(SceneAPI::Utilities::ErrorWindow, newIndex.IsValid(), "Failed to create SceneGraph node for attribute.");
if (!newIndex.IsValid())
{
return Events::ProcessingResult::Failure;
}
Events::ProcessingResult transformAttributeResult;
AssImpSceneAttributeDataPopulatedContext 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_Error(SceneAPI::Utilities::ErrorWindow, addedData, "Failed to add node data");
return addedData ? Events::ProcessingResult::Success : Events::ProcessingResult::Failure;
}
return Events::ProcessingResult::Ignored;
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,40 @@
/*
* 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/AssImpImportContexts.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
class AssImpTransformImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(AssImpTransformImporter, "{A7494C53-5822-40EF-9B60-B1FF09FBFA59}", SceneCore::LoadingComponent);
AssImpTransformImporter();
~AssImpTransformImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportTransform(AssImpSceneNodeAppendedContext& context);
static const char* s_transformNodeName;
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,117 @@
/*
* 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/Math/Vector2.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#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/SDKWrapper/AssImpNodeWrapper.h>
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexUVData.h>
#include <assimp/scene.h>
#include <assimp/mesh.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
const char* AssImpUvMapImporter::m_defaultNodeName = "UVMap";
AssImpUvMapImporter::AssImpUvMapImporter()
{
BindToCall(&AssImpUvMapImporter::ImportUvMaps);
}
void AssImpUvMapImporter::Reflect(ReflectContext* context)
{
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpUvMapImporter, SceneCore::LoadingComponent>()->Version(1);
}
}
Events::ProcessingResult AssImpUvMapImporter::ImportUvMaps(AssImpSceneNodeAppendedContext& context)
{
AZ_TraceContext("Importer", m_defaultNodeName);
if (!context.m_sourceNode.ContainsMesh())
{
return Events::ProcessingResult::Ignored;
}
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
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()))
{
return Events::ProcessingResult::Failure;
}
const SceneData::GraphData::MeshData* const parentMeshData =
azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
size_t vertexCount = parentMeshData->GetVertexCount();
int sdkMeshIndex = parentMeshData->GetSdkMeshIndex();
AZ_Assert(sdkMeshIndex >= 0,
"Tried to construct uv stream attribute for invalid or non-mesh parent data, mesh index is missing");
aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[sdkMeshIndex]];
if (!mesh->mTextureCoords[0])
{
return Events::ProcessingResult::Ignored;
}
Events::ProcessingResultCombiner combinedUvMapResults;
AZStd::shared_ptr<SceneData::GraphData::MeshVertexUVData> uvMap =
AZStd::make_shared<AZ::SceneData::GraphData::MeshVertexUVData>();
uvMap->ReserveContainerSpace(vertexCount);
uvMap->SetCustomName(m_defaultNodeName);
for (int v = 0; v < mesh->mNumVertices; ++v)
{
AZ::Vector2 vertexUV(
mesh->mTextureCoords[0][v].x,
mesh->mTextureCoords[0][v].y);
uvMap->AppendUV(vertexUV);
}
Containers::SceneGraph::NodeIndex newIndex =
context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, m_defaultNodeName);
Events::ProcessingResult uvMapResults;
AssImpSceneAttributeDataPopulatedContext dataPopulated(context, uvMap, newIndex, m_defaultNodeName);
uvMapResults = Events::Process(dataPopulated);
if (uvMapResults != Events::ProcessingResult::Failure)
{
uvMapResults = AddAttributeDataNodeWithContexts(dataPopulated);
}
combinedUvMapResults += uvMapResults;
return combinedUvMapResults.GetResult();
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,42 @@
/*
* 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/AssImpImportContexts.h>
#include <SceneAPI/SceneCore/Components/LoadingComponent.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
class AssImpUvMapImporter
: public SceneCore::LoadingComponent
{
public:
AZ_COMPONENT(AssImpUvMapImporter, "{BF02F231-848B-4CDB-9B11-55EEE15CFAA6}", SceneCore::LoadingComponent);
AssImpUvMapImporter();
~AssImpUvMapImporter() override = default;
static void Reflect(ReflectContext* context);
Events::ProcessingResult ImportUvMaps(AssImpSceneNodeAppendedContext& context);
protected:
static const char* m_defaultNodeName;
};
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ
@@ -0,0 +1,216 @@
/*
* 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();
int stackCount = context.m_sourceScene.GetAnimationStackCount();
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
@@ -0,0 +1,46 @@
/*
* 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
@@ -0,0 +1,160 @@
/*
* 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
@@ -0,0 +1,58 @@
/*
* 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
@@ -0,0 +1,128 @@
/*
* 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
@@ -0,0 +1,39 @@
/*
* 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
@@ -0,0 +1,84 @@
/*
* 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
@@ -0,0 +1,39 @@
/*
* 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
@@ -0,0 +1,163 @@
/*
* 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
@@ -0,0 +1,57 @@
/*
* 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
@@ -0,0 +1,507 @@
/*
* 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/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/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Containers/Views/PairIterator.h>
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphDownwardsIterator.h>
#include <SceneAPI/SceneData/GraphData/AnimationData.h>
#include <SceneAPI/SceneData/GraphData/BoneData.h>
#include <SceneAPI/SceneData/GraphData/MaterialData.h>
#include <SceneAPI/SceneData/GraphData/MeshData.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexColorData.h>
#include <SceneAPI/SceneData/GraphData/MeshVertexUVData.h>
#include <SceneAPI/SceneData/GraphData/SkinWeightData.h>
#include <SceneAPI/SceneData/GraphData/TransformData.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
static const float g_sceneUtilityEqualityEpsilon = 0.001f;
CoreProcessingResult AddDataNodeWithContexts(SceneDataPopulatedContextBase& dataPopulated)
{
AZ_TraceContext("Node Name", dataPopulated.m_dataName);
const char* nodeTypeName = dataPopulated.m_graphData ? dataPopulated.m_graphData->RTTI_GetTypeName() : "Null";
AZ_TraceContext("Node Type", (!nodeTypeName || nodeTypeName[0] == '\0' ? "Null" : nodeTypeName));
Events::ProcessingResultCombiner nodeResults;
nodeResults += Events::Process(dataPopulated);
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);
}
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
else
{
AssImpSceneDataPopulatedContext* dataPopulatedContext = azrtti_cast<AssImpSceneDataPopulatedContext*>(&dataPopulated);
AssImpSceneNodeAppendedContext nodeAppended(*dataPopulatedContext, dataPopulated.m_currentGraphPosition);
nodeResults += Events::Process(nodeAppended);
AssImpSceneNodeAddedAttributesContext addedAttributes(nodeAppended);
nodeResults += Events::Process(addedAttributes);
AssImpSceneNodeFinalizeContext finalizeNode(addedAttributes);
nodeResults += Events::Process(finalizeNode);
}
#endif
return nodeResults.GetResult();
}
CoreProcessingResult AddAttributeDataNodeWithContexts(SceneAttributeDataPopulatedContextBase& dataPopulated)
{
AZ_TraceContext("Node Name", dataPopulated.m_dataName);
const char* nodeTypeName = dataPopulated.m_graphData ? dataPopulated.m_graphData->RTTI_GetTypeName() : "Null";
AZ_TraceContext("Node Type", (!nodeTypeName || nodeTypeName[0] == '\0' ? "Null" : nodeTypeName));
Events::ProcessingResultCombiner nodeResults;
nodeResults += Events::Process(dataPopulated);
dataPopulated.m_scene.GetGraph().MakeEndPoint(dataPopulated.m_currentGraphPosition);
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);
}
#ifdef ASSET_IMPORTER_SDK_SUPPORTED_TRAIT
else
{
AssImpSceneAttributeDataPopulatedContext* dataPopulatedContext = azrtti_cast<AssImpSceneAttributeDataPopulatedContext*>(&dataPopulated);
AssImpSceneAttributeNodeAppendedContext nodeAppended(*dataPopulatedContext, dataPopulated.m_currentGraphPosition);
nodeResults += Events::Process(nodeAppended);
}
#endif
return nodeResults.GetResult();
}
bool AreSceneGraphsEqual(const CoreSceneGraph& lhsGraph, const CoreSceneGraph& rhsGraph)
{
auto lhsContentStorage = lhsGraph.GetContentStorage();
auto lhsNameStorage = lhsGraph.GetNameStorage();
auto lhsNameContentView = Containers::Views::MakePairView(lhsNameStorage, lhsContentStorage);
Containers::SceneGraph::NodeIndex lhsRootIndex = lhsGraph.GetRoot();
auto lhsDownwardView =
Containers::Views::MakeSceneGraphDownwardsView<Containers::Views::BreadthFirst>(lhsGraph, lhsRootIndex,
lhsNameContentView.begin(), true);
auto rhsContentStorage = rhsGraph.GetContentStorage();
auto rhsNameStorage = rhsGraph.GetNameStorage();
auto rhsNameContentView = Containers::Views::MakePairView(rhsNameStorage, rhsContentStorage);
Containers::SceneGraph::NodeIndex rhsRootIndex = rhsGraph.GetRoot();
auto rhsDownwardView =
Containers::Views::MakeSceneGraphDownwardsView<Containers::Views::BreadthFirst>(rhsGraph, rhsRootIndex,
rhsNameContentView.begin(), true);
auto lhsIt = lhsDownwardView.begin();
auto rhsIt = rhsDownwardView.begin();
while (lhsIt != lhsDownwardView.end() && rhsIt != rhsDownwardView.end())
{
if (!IsGraphDataEqual(lhsIt->second, rhsIt->second))
{
return false;
}
if (lhsIt->first != rhsIt->first)
{
return false;
}
++lhsIt;
++rhsIt;
}
return (lhsIt == lhsDownwardView.end() && rhsIt == rhsDownwardView.end());
}
bool operator==(const SceneData::GraphData::MeshData& lhs,
const SceneData::GraphData::MeshData& rhs)
{
if (lhs.GetVertexCount() != rhs.GetVertexCount())
{
return false;
}
if (lhs.HasNormalData() != rhs.HasNormalData())
{
return false;
}
if (lhs.GetFaceCount() != rhs.GetFaceCount())
{
return false;
}
bool hasNormals = lhs.HasNormalData();
unsigned int vertexCount = lhs.GetVertexCount();
for (unsigned int vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex)
{
if (lhs.GetPosition(vertexIndex) != rhs.GetPosition(vertexIndex))
{
return false;
}
if (hasNormals && (lhs.GetNormal(vertexIndex) != rhs.GetNormal(vertexIndex)))
{
return false;
}
}
unsigned int faceCount = lhs.GetFaceCount();
for (unsigned int faceIndex = 0; faceIndex < faceCount; ++faceIndex)
{
if (lhs.GetFaceMaterialId(faceIndex) != rhs.GetFaceMaterialId(faceIndex))
{
return false;
}
if (lhs.GetFaceInfo(faceIndex) != rhs.GetFaceInfo(faceIndex))
{
return false;
}
}
return true;
}
bool operator==(const SceneData::GraphData::SkinWeightData& lhs,
const SceneData::GraphData::SkinWeightData& rhs)
{
if (lhs.GetVertexCount() != rhs.GetVertexCount())
{
return false;
}
if (lhs.GetBoneCount() != rhs.GetBoneCount())
{
return false;
}
size_t vertexCount = lhs.GetVertexCount();
for (size_t vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex)
{
if (lhs.GetLinkCount(vertexIndex) != rhs.GetLinkCount(vertexIndex))
{
return false;
}
size_t linkCount = lhs.GetLinkCount(vertexIndex);
for (size_t linkIndex = 0; linkIndex < linkCount; ++linkIndex)
{
const DataTypes::ISkinWeightData::Link lhsLink = lhs.GetLink(vertexIndex, linkIndex);
const DataTypes::ISkinWeightData::Link rhsLink = rhs.GetLink(vertexIndex, linkIndex);
if (lhsLink.boneId != rhsLink.boneId || !IsClose(lhsLink.weight, rhsLink.weight, g_sceneUtilityEqualityEpsilon))
{
return false;
}
if (lhs.GetBoneName(lhsLink.boneId) != rhs.GetBoneName(rhsLink.boneId))
{
return false;
}
}
}
return true;
}
bool operator==(const SceneData::GraphData::BoneData& lhs,
const SceneData::GraphData::BoneData& rhs)
{
return (lhs.GetWorldTransform() == rhs.GetWorldTransform());
}
bool operator==(const DataTypes::Color& lhs, const DataTypes::Color& rhs)
{
if (!IsClose(lhs.alpha, rhs.alpha, g_sceneUtilityEqualityEpsilon) ||
!IsClose(lhs.blue, rhs.blue, g_sceneUtilityEqualityEpsilon) ||
!IsClose(lhs.green, rhs.green, g_sceneUtilityEqualityEpsilon) ||
!IsClose(lhs.red, rhs.red, g_sceneUtilityEqualityEpsilon))
{
return false;
}
return true;
}
bool operator!=(const DataTypes::Color& lhs, const DataTypes::Color& rhs)
{
return !(lhs == rhs);
}
bool operator==(const SceneData::GraphData::MeshVertexColorData& lhs,
const SceneData::GraphData::MeshVertexColorData& rhs)
{
if (lhs.GetCount() != rhs.GetCount())
{
return false;
}
size_t colorCount = lhs.GetCount();
for (size_t colorIndex = 0; colorIndex < colorCount; ++colorIndex)
{
if (lhs.GetColor(colorIndex) != rhs.GetColor(colorIndex))
{
return false;
}
}
return true;
}
bool operator==(const SceneData::GraphData::MeshVertexUVData& lhs,
const SceneData::GraphData::MeshVertexUVData& rhs)
{
if (lhs.GetCount() != rhs.GetCount())
{
return false;
}
size_t uvCount = lhs.GetCount();
for (size_t uvIndex = 0; uvIndex < uvCount; ++uvIndex)
{
if (lhs.GetUV(uvIndex) != rhs.GetUV(uvIndex))
{
return false;
}
}
return true;
}
bool operator==(const SceneData::GraphData::MaterialData& lhs,
const SceneData::GraphData::MaterialData& rhs)
{
if (lhs.IsNoDraw() != rhs.IsNoDraw())
{
return false;
}
if (lhs.GetTexture(DataTypes::IMaterialData::TextureMapType::Diffuse) !=
rhs.GetTexture(DataTypes::IMaterialData::TextureMapType::Diffuse))
{
return false;
}
if (lhs.GetTexture(DataTypes::IMaterialData::TextureMapType::Specular) !=
rhs.GetTexture(DataTypes::IMaterialData::TextureMapType::Specular))
{
return false;
}
if (lhs.GetTexture(DataTypes::IMaterialData::TextureMapType::Bump) !=
rhs.GetTexture(DataTypes::IMaterialData::TextureMapType::Bump))
{
return false;
}
return true;
}
bool operator==(const SceneData::GraphData::TransformData& lhs,
const SceneData::GraphData::TransformData& rhs)
{
return lhs.GetMatrix() == rhs.GetMatrix();
}
bool operator==(const SceneData::GraphData::AnimationData& lhs,
const SceneData::GraphData::AnimationData& rhs)
{
if (lhs.GetKeyFrameCount() != rhs.GetKeyFrameCount())
{
return false;
}
size_t keyFrameCount = lhs.GetKeyFrameCount();
for (size_t keyFrameIndex = 0; keyFrameIndex < keyFrameCount; ++keyFrameIndex)
{
if (lhs.GetKeyFrame(keyFrameIndex) != rhs.GetKeyFrame(keyFrameIndex))
{
return false;
}
}
return true;
}
bool IsGraphDataEqual(const AZStd::shared_ptr<const DataTypes::IGraphObject>& lhs,
const AZStd::shared_ptr<const DataTypes::IGraphObject>& rhs)
{
// If both are null, they are considered equal
if (!lhs && !rhs)
{
return true;
}
// If only one is null, they are considered not equal
if (!lhs || !rhs)
{
return false;
}
// If they have disparate types they are considered not equal
if (lhs->RTTI_GetType() != rhs->RTTI_GetType())
{
return false;
}
if (lhs->RTTI_IsTypeOf(SceneData::GraphData::BoneData::TYPEINFO_Uuid()))
{
const SceneData::GraphData::BoneData* lhsBone =
azrtti_cast<const SceneData::GraphData::BoneData*>(lhs.get());
const SceneData::GraphData::BoneData* rhsBone =
azrtti_cast<const SceneData::GraphData::BoneData*>(rhs.get());
return (*lhsBone == *rhsBone);
}
else if (lhs->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
{
const SceneData::GraphData::MeshData* lhsMesh =
azrtti_cast<const SceneData::GraphData::MeshData*>(lhs.get());
const SceneData::GraphData::MeshData* rhsMesh =
azrtti_cast<const SceneData::GraphData::MeshData*>(rhs.get());
return (*lhsMesh == *rhsMesh);
}
else if (lhs->RTTI_IsTypeOf(SceneData::GraphData::SkinWeightData::TYPEINFO_Uuid()))
{
const SceneData::GraphData::SkinWeightData* lhsSkinWeights =
azrtti_cast<const SceneData::GraphData::SkinWeightData*>(lhs.get());
const SceneData::GraphData::SkinWeightData* rhsSkinWeights =
azrtti_cast<const SceneData::GraphData::SkinWeightData*>(rhs.get());
return (*lhsSkinWeights == *rhsSkinWeights);
}
else if (lhs->RTTI_IsTypeOf(SceneData::GraphData::MeshVertexColorData::TYPEINFO_Uuid()))
{
const SceneData::GraphData::MeshVertexColorData* lhsColorData =
azrtti_cast<const SceneData::GraphData::MeshVertexColorData*>(lhs.get());
const SceneData::GraphData::MeshVertexColorData* rhsColorData =
azrtti_cast<const SceneData::GraphData::MeshVertexColorData*>(rhs.get());
return (*lhsColorData == *rhsColorData);
}
else if (lhs->RTTI_IsTypeOf(SceneData::GraphData::MeshVertexUVData::TYPEINFO_Uuid()))
{
const SceneData::GraphData::MeshVertexUVData* lhsUVData =
azrtti_cast<const SceneData::GraphData::MeshVertexUVData*>(lhs.get());
const SceneData::GraphData::MeshVertexUVData* rhsUVData =
azrtti_cast<const SceneData::GraphData::MeshVertexUVData*>(rhs.get());
return (*lhsUVData == *rhsUVData);
}
else if (lhs->RTTI_IsTypeOf(SceneData::GraphData::MaterialData::TYPEINFO_Uuid()))
{
const SceneData::GraphData::MaterialData* lhsMaterialData =
azrtti_cast<const SceneData::GraphData::MaterialData*>(lhs.get());
const SceneData::GraphData::MaterialData* rhsMaterialData =
azrtti_cast<const SceneData::GraphData::MaterialData*>(rhs.get());
return (*lhsMaterialData == *rhsMaterialData);
}
else if (lhs->RTTI_IsTypeOf(SceneData::GraphData::TransformData::TYPEINFO_Uuid()))
{
const SceneData::GraphData::TransformData* lhsTransform =
azrtti_cast<const SceneData::GraphData::TransformData*>(lhs.get());
const SceneData::GraphData::TransformData* rhsTransform =
azrtti_cast<const SceneData::GraphData::TransformData*>(rhs.get());
return (*lhsTransform == *rhsTransform);
}
else if (lhs->RTTI_IsTypeOf(SceneData::GraphData::AnimationData::TYPEINFO_Uuid()))
{
const SceneData::GraphData::AnimationData* lhsAnimation =
azrtti_cast<const SceneData::GraphData::AnimationData*>(lhs.get());
const SceneData::GraphData::AnimationData* rhsAnimation =
azrtti_cast<const SceneData::GraphData::AnimationData*>(rhs.get());
return (*lhsAnimation == *rhsAnimation);
}
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
@@ -0,0 +1,63 @@
/*
* 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/DataTypes/MatrixType.h>
#include <SceneAPI/SceneCore/Events/CallProcessorBus.h>
namespace AZ
{
struct Uuid;
namespace FbxSDKWrapper
{
class FbxNodeWrapper;
class FbxSceneWrapper;
}
namespace SceneAPI
{
namespace FbxSceneBuilder
{
struct FbxImportContext;
using CoreScene = Containers::Scene;
using CoreSceneGraph = Containers::SceneGraph;
using CoreGraphNodeIndex = Containers::SceneGraph::NodeIndex;
using CoreProcessingResult = Events::ProcessingResult;
inline bool NodeIsOfType(const CoreSceneGraph& graph, CoreGraphNodeIndex nodeIndex, const AZ::Uuid& uuid);
inline bool NodeParentIsOfType(const CoreSceneGraph& graph, CoreGraphNodeIndex nodeIndex,
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);
inline bool AreScenesEqual(const CoreScene& lhs, const CoreScene& rhs);
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>
@@ -0,0 +1,82 @@
/*
* 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/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
#include <SceneAPI/FbxSDKWrapper/FbxNodeWrapper.h>
#include <SceneAPI/FbxSDKWrapper/FbxSkinWrapper.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/DataTypes/IGraphObject.h>
namespace AZ
{
namespace SceneAPI
{
namespace FbxSceneBuilder
{
bool NodeIsOfType(const CoreSceneGraph& sceneGraph, CoreGraphNodeIndex nodeIndex, const AZ::Uuid& uuid)
{
if (nodeIndex.IsValid() && sceneGraph.HasNodeContent(nodeIndex) &&
sceneGraph.GetNodeContent(nodeIndex)->RTTI_IsTypeOf(uuid))
{
return true;
}
else
{
return false;
}
}
bool NodeParentIsOfType(const CoreSceneGraph& sceneGraph, CoreGraphNodeIndex nodeIndex, const AZ::Uuid& uuid)
{
CoreGraphNodeIndex parentIndex = sceneGraph.GetNodeParent(nodeIndex);
return NodeIsOfType(sceneGraph, parentIndex, uuid);
}
bool NodeHasAncestorOfType(const CoreSceneGraph& sceneGraph, CoreGraphNodeIndex nodeIndex, const AZ::Uuid& uuid)
{
CoreGraphNodeIndex parentIndex = sceneGraph.GetNodeParent(nodeIndex);
while (parentIndex.IsValid())
{
if (NodeIsOfType(sceneGraph, parentIndex, uuid))
{
return true;
}
parentIndex = sceneGraph.GetNodeParent(parentIndex);
}
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())
{
return false;
}
if (!AreSceneGraphsEqual(lhs.GetGraph(), rhs.GetGraph()))
{
return false;
}
return true;
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
} // namespace AZ

Some files were not shown because too many files have changed in this diff Show More