| <!DOCTYPE html> |
| <body> |
| <script src=/resources/testharness.js></script> |
| <script src=/resources/testharnessreport.js></script> |
| <script src="resources/webxr_util.js"></script> |
| <script src="resources/webxr_test_constants.js"></script> |
| <script src="resources/webxr_test_asserts.js"></script> |
| |
| <script> |
| |
| let testName = "XRFrame getViewerPose(viewerSpace) & getPose(space, space) return identity even during tracking loss"; |
| |
| // Use the same device as tracked immersive device, but modify the viewer origin. |
| const deviceInitParams = Object.assign({}, TRACKED_IMMERSIVE_DEVICE, {viewerOrigin: null}); |
| |
| // Used when creating a reference space that is offset from local space. |
| // Actual values should not matter for the test. |
| const offsetSpaceTransform = new XRRigidTransform( |
| { x: 1.00, y: -1.50, z: 10.00, w: 1.0 }, |
| { x: 0.27, y: 0.00, z: 0.27, w: 0.92}, // 45 degrees around [1, 0, 1] axis |
| ); |
| |
| const expectMatrix = function(pose, expectedMatrix, poseName) { |
| assert_not_equals(pose, null, |
| poseName + " should not be null!"); |
| assert_matrix_approx_equals(pose.transform.matrix, expectedMatrix, |
| poseName + "'s matrix should match expectations!"); |
| assert_false(pose.emulatedPosition, |
| poseName + ".emulatedPosition should be false!"); |
| } |
| |
| const expectIdentity = function(pose, poseName) { |
| assert_not_equals(pose, null, |
| poseName + " should not be null!"); |
| assert_matrix_approx_equals(pose.transform.matrix, IDENTITY_MATRIX, |
| poseName + "'s matrix should equal identity!"); |
| assert_false(pose.emulatedPosition, |
| poseName + ".emulatedPosition should be false!"); |
| } |
| |
| const testFunction = function(session, fakeDeviceController, t) { |
| return Promise.all([ |
| session.requestReferenceSpace('local'), |
| session.requestReferenceSpace('viewer'), |
| session.requestReferenceSpace('local-floor'), |
| session.requestReferenceSpace('bounded-floor'), |
| session.requestReferenceSpace('unbounded'), |
| session.requestReferenceSpace('local'), |
| ]).then((allSpaces) => new Promise((resolve, reject) => { |
| const [ |
| localSpace1, |
| viewerSpace, |
| localFloorSpace, |
| boundedFloorSpace, |
| unboundedSpace, |
| localSpace2] = allSpaces; |
| |
| const offsetLocalSpace1 = localSpace1.getOffsetReferenceSpace(offsetSpaceTransform); |
| const offsetLocalSpace2 = localSpace2.getOffsetReferenceSpace(offsetSpaceTransform); |
| const offsetViewerSpace = viewerSpace.getOffsetReferenceSpace(offsetSpaceTransform); |
| |
| // Throw in an offset space: |
| allSpaces.push(offsetLocalSpace1); |
| |
| function onFrame(time, frame) { |
| // Expect identities: |
| const viewerFromViewer1 = frame.getViewerPose(viewerSpace); |
| |
| const localFromLocalDifferentAddress = frame.getPose(localSpace1, localSpace2); |
| const offsetFromOffsetDifferentAddress = frame.getPose(offsetLocalSpace1, offsetLocalSpace2); |
| |
| t.step(() => { |
| expectIdentity(viewerFromViewer1, "viewerFromViewer1"); |
| expectIdentity(localFromLocalDifferentAddress, "localFromLocalDifferentAddress"); |
| expectIdentity(offsetFromOffsetDifferentAddress, "offsetFromOffsetDifferentAddress"); |
| }); |
| |
| // Expect offsetSpaceTransform: |
| const viewerFromViewer2 = frame.getViewerPose(offsetViewerSpace); |
| |
| const viewerFromOffset2 = frame.getPose(offsetViewerSpace, viewerSpace); |
| const localFromOffset1 = frame.getPose(offsetLocalSpace1, localSpace1); |
| const localFromOffset2 = frame.getPose(offsetLocalSpace2, localSpace1); |
| |
| t.step(() => { |
| expectMatrix(viewerFromViewer2, offsetSpaceTransform.matrix, "viewerFromViewer2"); |
| expectMatrix(viewerFromOffset2, offsetSpaceTransform.matrix, "viewerFromOffset2"); |
| expectMatrix(localFromOffset1, offsetSpaceTransform.matrix, "localFromOffset1"); |
| expectMatrix(localFromOffset2, offsetSpaceTransform.matrix, "localFromOffset2"); |
| }); |
| |
| // Expect identities: |
| allSpaces.forEach((space, index) => { |
| const pose = frame.getPose(space, space); |
| t.step(() => { |
| expectIdentity(pose, "pose[" + index +"]"); |
| }); |
| }); |
| |
| resolve(); |
| } |
| |
| session.requestAnimationFrame(onFrame); |
| })); |
| }; |
| |
| xr_session_promise_test(testName, testFunction, |
| deviceInitParams, 'immersive-vr', { |
| requiredFeatures: ["local", "local-floor", "bounded-floor", "unbounded"] |
| }); |
| |
| </script> |
| </body> |