170 lines
5.1 KiB
C++
170 lines
5.1 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "FbxConvert.h"
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "FbxInclude.h"
|
|
|
|
#define CONVERT_TO_FRONT_X 0
|
|
|
|
namespace UE
|
|
{
|
|
namespace Interchange
|
|
{
|
|
namespace Private
|
|
{
|
|
FString GetFileAxisDirection(FbxAxisSystem FileAxisSystem)
|
|
{
|
|
FString AxisDirection;
|
|
int32 Sign = 1;
|
|
switch (FileAxisSystem.GetUpVector(Sign))
|
|
{
|
|
case FbxAxisSystem::eXAxis:
|
|
{
|
|
AxisDirection += TEXT("X");
|
|
}
|
|
break;
|
|
case FbxAxisSystem::eYAxis:
|
|
{
|
|
AxisDirection += TEXT("Y");
|
|
}
|
|
break;
|
|
case FbxAxisSystem::eZAxis:
|
|
{
|
|
AxisDirection += TEXT("Z");
|
|
}
|
|
break;
|
|
}
|
|
|
|
//Negative sign mean down instead of up
|
|
AxisDirection += Sign == 1 ? TEXT("-UP") : TEXT("-DOWN");
|
|
|
|
switch (FileAxisSystem.GetCoorSystem())
|
|
{
|
|
case FbxAxisSystem::eLeftHanded:
|
|
{
|
|
AxisDirection += TEXT(" (LH)");
|
|
}
|
|
break;
|
|
case FbxAxisSystem::eRightHanded:
|
|
{
|
|
AxisDirection += TEXT(" (RH)");
|
|
}
|
|
break;
|
|
}
|
|
return AxisDirection;
|
|
}
|
|
|
|
void FFbxConvert::ConvertScene(FbxScene* SDKScene,
|
|
const bool bConvertScene, const bool bForceFrontXAxis, const bool bConvertSceneUnit,
|
|
FString& FileSystemDirection, FString& FileUnitSystem,
|
|
FbxAMatrix& AxisConversionInverseMatrix, FbxAMatrix& JointOrientationMatrix)
|
|
{
|
|
if (!ensure(SDKScene))
|
|
{
|
|
//Cannot convert a null scene
|
|
return;
|
|
}
|
|
|
|
const FbxGlobalSettings& GlobalSettings = SDKScene->GetGlobalSettings();
|
|
FbxTime::EMode TimeMode = GlobalSettings.GetTimeMode();
|
|
//Set the original framerate from the current fbx file
|
|
float FbxFramerate = FbxTime::GetFrameRate(TimeMode);
|
|
|
|
//Apply any curve filter here, we currently do not apply any
|
|
//The unroll curve filter was apply in legacy fbx importer if there was more then one FbxAnimStack.
|
|
//The unroll curve filter can obliterate curve keys if for example a key do a complete rotation (360 degree in euler)
|
|
|
|
FbxAxisSystem FileAxisSystem = SDKScene->GetGlobalSettings().GetAxisSystem();
|
|
FileSystemDirection = GetFileAxisDirection(FileAxisSystem);
|
|
|
|
AxisConversionInverseMatrix.SetIdentity();
|
|
JointOrientationMatrix.SetIdentity();
|
|
|
|
if (bConvertScene)
|
|
{
|
|
//UE is: z up, front x, left handed
|
|
FbxAxisSystem::EUpVector UpVector = FbxAxisSystem::EUpVector::eZAxis;
|
|
FbxAxisSystem::EFrontVector FrontVector = (FbxAxisSystem::EFrontVector)(bForceFrontXAxis ? FbxAxisSystem::eParityEven : -FbxAxisSystem::eParityOdd);
|
|
FbxAxisSystem::ECoordSystem CoordSystem = FbxAxisSystem::ECoordSystem::eRightHanded;
|
|
FbxAxisSystem UnrealImportAxis(UpVector, FrontVector, CoordSystem);
|
|
|
|
if (FileAxisSystem != UnrealImportAxis)
|
|
{
|
|
FbxRootNodeUtility::RemoveAllFbxRoots(SDKScene);
|
|
UnrealImportAxis.ConvertScene(SDKScene);
|
|
|
|
FbxAMatrix SourceMatrix;
|
|
FileAxisSystem.GetMatrix(SourceMatrix);
|
|
FbxAMatrix UnrealMatrix;
|
|
UnrealImportAxis.GetMatrix(UnrealMatrix);
|
|
|
|
FbxAMatrix AxisConversionMatrix;
|
|
AxisConversionMatrix = SourceMatrix.Inverse() * UnrealMatrix;
|
|
AxisConversionInverseMatrix = AxisConversionMatrix.Inverse();
|
|
|
|
if (bForceFrontXAxis)
|
|
{
|
|
JointOrientationMatrix.SetR(FbxVector4(-90.0, -90.0, 0.0));
|
|
}
|
|
}
|
|
}
|
|
|
|
FbxSystemUnit OriginalFileUnitSystem = SDKScene->GetGlobalSettings().GetSystemUnit();
|
|
FileUnitSystem = FString(UTF8_TO_TCHAR(OriginalFileUnitSystem.GetScaleFactorAsString(false).Buffer()));
|
|
|
|
if (bConvertSceneUnit)
|
|
{
|
|
if (OriginalFileUnitSystem != FbxSystemUnit::cm)
|
|
{
|
|
FbxSystemUnit::cm.ConvertScene(SDKScene);
|
|
}
|
|
}
|
|
|
|
//Reset all the transform evaluation cache since we change some node transform
|
|
SDKScene->GetAnimationEvaluator()->Reset();
|
|
}
|
|
|
|
|
|
FTransform FFbxConvert::AdjustCameraTransform(const FTransform& Transform)
|
|
{
|
|
//Add a roll of -90 degree locally for every cameras. Camera up vector differ from fbx to unreal
|
|
const FRotator AdditionalRotation(0.0f, 0.0f, -90.0f);
|
|
FTransform CameraTransform = FTransform(AdditionalRotation) * Transform;
|
|
|
|
//Remove the scale of the node holding a camera (the mesh is provide by the engine and can be different in size)
|
|
CameraTransform.SetScale3D(FVector::OneVector);
|
|
|
|
return CameraTransform;
|
|
}
|
|
|
|
FTransform FFbxConvert::AdjustLightTransform(const FTransform& Transform)
|
|
{
|
|
//Add the z rotation of 90 degree locally for every light. Light direction differ from fbx to unreal
|
|
const FRotator AdditionalRotation(0.0f, 90.0f, 0.0f);
|
|
FTransform LightTransform = FTransform(AdditionalRotation) * Transform;
|
|
return LightTransform;
|
|
}
|
|
|
|
FLinearColor FFbxConvert::ConvertColor(const FbxDouble3& Color)
|
|
{
|
|
FLinearColor LinearColor;
|
|
LinearColor.R =(float)Color[0];
|
|
LinearColor.G =(float)Color[1];
|
|
LinearColor.B =(float)Color[2];
|
|
LinearColor.A = 1.f;
|
|
|
|
return LinearColor;
|
|
}
|
|
|
|
/**
|
|
* Convert UTF8 char to a FString using ANSI_TO_TCHAR macro
|
|
*/
|
|
FString FFbxConvert::MakeString(const ANSICHAR* Name)
|
|
{
|
|
return FString(UTF8_TO_TCHAR(Name));
|
|
}
|
|
}//ns Private
|
|
}//ns Interchange
|
|
}//ns UE
|