From 4f2e41202c7238b4f8f28661a2a6796d567bff93 Mon Sep 17 00:00:00 2001 From: Branimir Karadzic Date: Fri, 16 Oct 2026 13:10:32 -0700 Subject: [PATCH] Make camera rotation tests independent of LookDirection handedness Babylon.js #18932 (first released in 9.31.0) changed what Quaternion.FromLookDirectionLH/RH return for a given forward vector. Babylon.js updated its own visualization config for the four "GLTF Serializer camera rotation animation" tests. The Native tests job in Babylon.js CI runs Babylon Native's config.json against the current Babylon.js build, so these tests now fail there (about 12.5% pixel difference, the model faces away from the camera). Babylon Native itself still pins babylonjs 9.29.0, which has the old behavior, so the Babylon.js replacement cannot be copied as is. Instead, detect the behavior at runtime: the new LookDirection returns identity for FromLookDirectionLH(Forward, Up), and in that case use Vector3.Backward to keep the original orientation. Verified locally on tests 227-230 with babylonjs 9.29.0 and 9.31.0 (4/4 pass on each); the previous config fails on 9.31.0 at 12.46%. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 60c2ec68-6de1-445d-9fc9-b699db737eae --- Apps/Playground/Scripts/config.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Apps/Playground/Scripts/config.json b/Apps/Playground/Scripts/config.json index ce10ad3a6..0fa8c0ffb 100644 --- a/Apps/Playground/Scripts/config.json +++ b/Apps/Playground/Scripts/config.json @@ -1377,7 +1377,7 @@ { "title": "GLTF Serializer camera rotation animation, RH -> LH", "playgroundId": "#3A00GJ#42", - "replace": "//options//, roundtripCount = 1; srcRH = true; destRH = false;", + "replace": "//options//, roundtripCount = 1; srcRH = true; destRH = false; const lookArgs = [BABYLON.Vector3.Forward()]; lookArgs.push(BABYLON.Vector3.Up()); const lookForward = Math.abs(BABYLON.Quaternion.FromLookDirectionLH(...lookArgs).w) > 0.5 ? BABYLON.Vector3.Backward : BABYLON.Vector3.Forward;, FromLookDirectionLH(BABYLON.Vector3.Forward, FromLookDirectionLH(lookForward, FromLookDirectionRH(BABYLON.Vector3.Forward, FromLookDirectionRH(lookForward", "workarounds": ["refresh-export-matrices"], "errorRatio": 3.5, "referenceImage": "glTFSerializerCameraRotationAnimation.png" @@ -1385,7 +1385,7 @@ { "title": "GLTF Serializer camera rotation animation, RH -> RH", "playgroundId": "#3A00GJ#42", - "replace": "//options//, roundtripCount = 1; srcRH = true; destRH = true;", + "replace": "//options//, roundtripCount = 1; srcRH = true; destRH = true; const lookArgs = [BABYLON.Vector3.Forward()]; lookArgs.push(BABYLON.Vector3.Up()); const lookForward = Math.abs(BABYLON.Quaternion.FromLookDirectionLH(...lookArgs).w) > 0.5 ? BABYLON.Vector3.Backward : BABYLON.Vector3.Forward;, FromLookDirectionLH(BABYLON.Vector3.Forward, FromLookDirectionLH(lookForward, FromLookDirectionRH(BABYLON.Vector3.Forward, FromLookDirectionRH(lookForward", "workarounds": ["refresh-export-matrices"], "errorRatio": 3.5, "referenceImage": "glTFSerializerCameraRotationAnimation.png" @@ -1393,7 +1393,7 @@ { "title": "GLTF Serializer camera rotation animation, LH -> RH", "playgroundId": "#3A00GJ#42", - "replace": "//options//, roundtripCount = 1; srcRH = false; destRH = true;", + "replace": "//options//, roundtripCount = 1; srcRH = false; destRH = true; const lookArgs = [BABYLON.Vector3.Forward()]; lookArgs.push(BABYLON.Vector3.Up()); const lookForward = Math.abs(BABYLON.Quaternion.FromLookDirectionLH(...lookArgs).w) > 0.5 ? BABYLON.Vector3.Backward : BABYLON.Vector3.Forward;, FromLookDirectionLH(BABYLON.Vector3.Forward, FromLookDirectionLH(lookForward, FromLookDirectionRH(BABYLON.Vector3.Forward, FromLookDirectionRH(lookForward", "workarounds": ["refresh-export-matrices"], "errorRatio": 3.5, "referenceImage": "glTFSerializerCameraRotationAnimation.png" @@ -1401,7 +1401,7 @@ { "title": "GLTF Serializer camera rotation animation, LH -> LH", "playgroundId": "#3A00GJ#42", - "replace": "//options//, roundtripCount = 1; srcRH = false; destRH = false;", + "replace": "//options//, roundtripCount = 1; srcRH = false; destRH = false; const lookArgs = [BABYLON.Vector3.Forward()]; lookArgs.push(BABYLON.Vector3.Up()); const lookForward = Math.abs(BABYLON.Quaternion.FromLookDirectionLH(...lookArgs).w) > 0.5 ? BABYLON.Vector3.Backward : BABYLON.Vector3.Forward;, FromLookDirectionLH(BABYLON.Vector3.Forward, FromLookDirectionLH(lookForward, FromLookDirectionRH(BABYLON.Vector3.Forward, FromLookDirectionRH(lookForward", "workarounds": ["refresh-export-matrices"], "errorRatio": 3.5, "referenceImage": "glTFSerializerCameraRotationAnimation.png"