fbx_sdk_transform_question

Kallocasia
Observer
Observer

fbx_sdk_transform_question

Kallocasia
Observer
Observer

Hello,

Below is a crane one of our artist created. We are currently using Fbx SDK 2020.2.1 and what we notices is that the boom is scaled very tiny see FbxSdk_tiny_boom.png.
In some softwares, i.e. Maya2023, FBX Review (1.3.1.0) the boom is scaled correctly. But in others, i.e. Rhino 6.0/Naviswork 2023, MS Paint3D, Visual Studio 2017, the boom is scaled tiny. I have no ideas what the other softwares are using internally to parse the fbx, but at least in our software we are seeing the same incorrect behaviour as Rhino, Navisworks etc...

Below is the code we used to fetch the matrices...

 

I have also attached the FBX file and pictures of the problem.

 

FbxSdk_tiny_boom.pngFbxSdk_tiny_boom_zoom_In.pngThanks,

 

Grace

 

// Contains the geometry transform (not inherited!)
	FbxAMatrix GetGlobalTransform ( FbxNode *a_pNode )
	{
		FbxVector4 vGeoTransform = a_pNode->GetGeometricTranslation ( FbxNode::eSourcePivot );
		FbxVector4 vGeoScale = a_pNode->GetGeometricScaling ( FbxNode::eSourcePivot );
		FbxVector4 vGeoRotate = a_pNode->GetGeometricRotation ( FbxNode::eSourcePivot );
		FbxAMatrix mGeoFull ( vGeoTransform, vGeoRotate, vGeoScale );
		FbxAMatrix mNodeTransform = a_pNode->EvaluateGlobalTransform();
		return mNodeTransform * mGeoFull;
	}
  
  
  
void FBXModelLoader::AppendMesh ( FbxNode *a_pNode, FbxMesh *a_pMesh, const FbxAMatrix &a_mLocal, KEHashMap64 *a_pUniqueMaterials, bool a_bUndoMirroring )
{
	if ( a_bUndoMirroring )
	{
		FbxAMatrix mWorld = GetGlobalTransform ( a_pNode );
		Matrix mMyProgWorld = FbxAMatrixToMyProgramMatrix ( mWorld );
		if ( !Matrix_Mirrored ( &mMyProgWorld ) )
		{
			a_bUndoMirroring = false;
		}
	}

	FbxAMatrix mGlobalTransformInvScaling = a_mLocal;

	if (m_bUseParentNodeXForm)
	{
		FbxNode *pParentNode = a_pNode->GetParent();
		if ( pParentNode )
		{
			FbxAMatrix mInvUnitMatrix = pParentNode->EvaluateGlobalTransform();
			mGlobalTransformInvScaling = mInvUnitMatrix.Inverse() * mGlobalTransformInvScaling;
		}
	}
  ...
 }
  
void FBXModelLoader::WriteEntities ( FbxNode *a_pNode, u32 dwModelId, Handle *a_pCacheEntryHandle, const FbxAMatrix &a_mInvBaseTransform, KEHashMap64 *a_pUniqueMaterials, bool a_bUndoMirroring )
{
	if ( !a_pNode || a_pNode->GetObjectFlags ( FbxObject::eHidden ) )
	{
		return;
	}

	KEHashMap64 uniqueMaterials;
	FbxAMatrix mWorld = GetGlobalTransform ( a_pNode );
	FbxAMatrix mLocal = a_mInvBaseTransform * mWorld;

	bool bCreateMesh = false;
	if ( HasMesh ( a_pNode ) )
	{
		const u32 dwNumAttributes = a_pNode->GetNodeAttributeCount();
		for ( u32 dwAttrIdx = 0; dwAttrIdx < dwNumAttributes; dwAttrIdx++ )
		{
			const FbxNodeAttribute *pCurAttribute = a_pNode->GetNodeAttributeByIndex ( dwAttrIdx );
			if ( pCurAttribute && pCurAttribute->GetAttributeType() == FbxNodeAttribute::eMesh && !pCurAttribute->GetObjectFlags ( FbxObject::eHidden ) )
			{
				FbxMesh *pMesh = (FbxMesh *)pCurAttribute;
				AppendMesh ( a_pNode, pMesh, mLocal, a_pUniqueMaterials, a_bUndoMirroring );
			}
		}
	}

	for ( s32 i = 0; i < a_pNode->GetChildCount(); i++ )
	{
		WriteEntities ( a_pNode->GetChild ( i ), dwModelId, a_pCacheEntryHandle, a_mInvBaseTransform, a_pUniqueMaterials, a_bUndoMirroring );
	}
  ...
  }
  
  
  ----------------- Start ---
  	m_pImporter->Import ( m_pScene );

	FbxAxisSystem engineAxis ( FbxAxisSystem::OpenGL );
	FbxSystemUnit engineUnit ( FbxSystemUnit::m );
	const FbxSystemUnit &unit = m_pScene->GetGlobalSettings().GetSystemUnit();
	const FbxAxisSystem &axis = m_pScene->GetGlobalSettings().GetAxisSystem();

	if ( unit != engineUnit )
	{
		engineUnit.ConvertScene ( m_pScene );
	}

	if ( axis != engineAxis )
	{
		engineAxis.ConvertScene ( m_pScene );
	}

	{
		FbxGeometryConverter lGeomConverter( m_pSdkManager );
		lGeomConverter.Triangulate( m_pScene, true );
	}

	FbxNode *pRootNode = m_pScene->GetRootNode();
	if ( pRootNode )
	{
		WriteEntities ( pRootNode, 0, nullptr, FbxAMatrix(), &uniqueMats, true );
  }
 }
 

 

 

0 Likes
Reply
286 Views
1 Reply
Reply (1)

regalir
Autodesk
Autodesk

Hi,

 

I don't know exactly how the programs you listed (besides Maya and FBXReview) handle the Scale Inheritance flag and unit conversions. I did notice that your scene in the file is already defined to be in "meters" and "OpenGL" so the calls to ConvertScene() will do nothing in your code. BTW the ifs tests

unit != engineUnit

  or if

axis != engineAxis

are not absolutely necessary because the FbxSystemUnit and FbxAxisSystem are performing the equality comparison  internally and do nothing if the condition is true!

 

I have noticed that "Arm" and "JibHeight" have the "Scale inheritance" flag set to "Scale Compensate".

Maya, FBXReview and the sample ViewScene internal system units are always in "centimeters" so your scene file does get a conversion and the unit scale factor is properly propagated/adjusted to take into account the "Scale Inheritance" flag. I suspect that the other programs you mentioned are:

  1. not applying an FbxSystemUnit conversion?
  2. their internal system is already in "meters" and no conversion is applied?
  3. It is also possible, although not likely, that they explicitly configured the FbxUnitSystem to not adjust the scaling on the nodes that have the "Scale Compensate" set (they set the mConvertRrsNodes state of the ConversionOptions structure to false)?

It looks like, MS Paint 3D does not like units other that centimeters. I converted your file to cm and also to inches (see the attached zip. Both FBX files are in ascii so you can inspect them with a text editor as well) and you can see that they load into MS Paint 3D "almost" fine! Actually, the centimeters file looks really okay but the inches ones have the crane boom shorter (0.39 of its length ;-)) showing that Paint 3D does not like units too far from the centimeters 😞

 

0 Likes