GLTFUtility icon indicating copy to clipboard operation
GLTFUtility copied to clipboard

Transform matrices in scene hierarchy not interpreted correctly.

Open nwessing opened this issue 4 years ago • 1 comments

I have a stripped down example here where the GTLFUtility does not generate the correct transform for a particular node. Here is the file

gltf_files.zip

Here is how the model should be rendered (screenshot from Windows 3D viewer): Windows3DViewer

Here is how the model is rendered after imported into Unity with GLTFUtility: GltfUtilityUnity

I have tested this in several other GLTF viewers and they all match behavior with Windows 3D Viewer. Babylon.js Babylonjs

Cesium Cesium

Filament Filament

Threejs Threejs

Khronos's GLTF importer interprets the matrix a bit differently than this importer does. https://github.com/KhronosGroup/UnityGLTF/blob/1e003333698be2d6026211c2ee85ddbd25d07b72/UnityGLTF/Assets/UnityGLTF/Runtime/Scripts/Extensions/SchemaExtensions.cs#L171

https://github.com/KhronosGroup/UnityGLTF/blob/1e003333698be2d6026211c2ee85ddbd25d07b72/UnityGLTF/Assets/UnityGLTF/Runtime/Scripts/Extensions/SchemaExtensions.cs#L42

nwessing avatar Nov 08 '21 18:11 nwessing

I'm surprised, this bug hasn't been fixed yet since it makes the tool basically unusable.

This is how you fix it based on the code that @nwessing posted: Change the ApplyTRS method in GLTFNode.cs to this:

/// <summary> Set local position, rotation and scale </summary>
public void ApplyTRS(Transform transform) {
	/// glTF is a right-handed coordinate system, where the 'right' direction is -X relative to Unity's coordinate system.
	/// glTF matrix: column vectors, column-major storage, +Y up, +Z forward, -X right, right-handed
	/// Unity matrix: column vectors, column-major storage, +Y up, +Z forward, +X right, left-handed
	/// Multiply by a negative X scale to convert handedness
	Vector3 coordinateSpaceConversionScale = new Vector3(-1, 1, 1);
	if (matrix != Matrix4x4.identity)
	{
		Matrix4x4 convert = Matrix4x4.Scale(coordinateSpaceConversionScale);
		Matrix4x4 matrixLH = convert * matrix * convert;

		transform.localPosition = matrixLH.GetColumn(3);

		Vector3 x = matrixLH.GetColumn(0);
		Vector3 y = matrixLH.GetColumn(1);
		Vector3 z = matrixLH.GetColumn(2);
		Vector3 calculatedZ = Vector3.Cross(x, y);
		bool mirrored = Vector3.Dot(calculatedZ, z) < 0.0f;
		transform.localScale = new Vector3(x.magnitude * (mirrored ? -1.0f : 1.0f), y.magnitude, z.magnitude);

		transform.localRotation = Quaternion.LookRotation(matrixLH.GetColumn(2), matrixLH.GetColumn(1));
	}
	else
	{
		transform.localPosition = Vector3.Scale(translation, coordinateSpaceConversionScale);

		Vector3 fromAxisOfRotation = new Vector3(rotation.x, rotation.y, rotation.z);
		Vector3 toAxisOfRotation = -1.0f * Vector3.Scale(fromAxisOfRotation, coordinateSpaceConversionScale);
		transform.localRotation = new Quaternion(toAxisOfRotation.x, toAxisOfRotation.y, toAxisOfRotation.z, rotation.w);

		transform.localScale = scale;
	}
}

code-monkey-101 avatar Mar 07 '22 16:03 code-monkey-101