Open nwessing opened 2 years ago
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;
}
}
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):
Here is how the model is rendered after imported into Unity with GLTFUtility:
I have tested this in several other GLTF viewers and they all match behavior with Windows 3D Viewer. Babylon.js
Cesium
Filament
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