<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/webxr_test_constants.js"></script>
<script src="resources/webxr_util.js"></script>
<script src="resources/webxr_test_asserts.js"></script>

<script>

let immersiveTestName = "XRFrame.getPose works for immersive sessions";
let nonImmersiveTestName = "XRFrame.getPose works for non-immersive sessions";

let fakeDeviceInitParams = TRACKED_IMMERSIVE_DEVICE;

let testFunction = function(session, fakeDeviceController, t) {
  return Promise.all([
    session.requestReferenceSpace('local'),
    session.requestReferenceSpace('local')
  ]).then((spaces) => new Promise((resolve) => {
    function onFrame(time, xrFrame) {
      const radians = Math.PI / 2.0; // 90 degrees

      // Both eye-level spaces start out with originOffset = identity matrix.
      let space1 = spaces[0];
      let space2 = spaces[1];

      let offset = new XRRigidTransform(
        DOMPointReadOnly.fromPoint({
          x: 2,
          y: 3,
          z: 4,
          w: 1,
        }));

      let translatedSpace1 = space1.getOffsetReferenceSpace(offset);
      let translated_from_base = xrFrame.getPose(translatedSpace1, space1);

      // Getting the transform of an offset space from the space it was based on
      // should be the same as the initially applied offset.
      t.step(() => {
        assert_matrix_approx_equals(translated_from_base.transform.matrix, offset.matrix, FLOAT_EPSILON);
      });

      // Rotate 90 degrees about x axis, then move 1 meter along y axis.
      space1 = space1.getOffsetReferenceSpace(new XRRigidTransform(
        DOMPointReadOnly.fromPoint({
          x : 0,
          y : 1,
          z : 0,
          w : 1
        }),
        DOMPointReadOnly.fromPoint({
          x : Math.sin(radians / 2),
          y : 0,
          z : 0,
          w : Math.cos(radians / 2)
        })
      ));

      // Rotate 90 degrees about z axis, then move 1 meter along x axis.
      space2 = space2.getOffsetReferenceSpace(new XRRigidTransform(
        DOMPointReadOnly.fromPoint({
          x : 1,
          y : 0,
          z : 0,
          w : 1
        }),
        DOMPointReadOnly.fromPoint({
          x : 0,
          y : 0,
          z : Math.sin(radians / 2),
          w : Math.cos(radians / 2)
        })
      ));

      let space2_from_space1 = xrFrame.getPose(space1, space2);
      const EXPECTED_POSE_MATRIX = [
         0, -1, 0, 0, // 1st column
         0,  0, 1, 0, // 2nd column
        -1,  0, 0, 0, // 3rd column
         1,  1, 0, 1 // 4th column
      ];

      t.step(() => {
        assert_matrix_approx_equals(space2_from_space1.transform.matrix, EXPECTED_POSE_MATRIX, FLOAT_EPSILON);
      });

      // Finished test.
      resolve();
    }

    session.requestAnimationFrame(onFrame);
  }));
};

xr_session_promise_test(immersiveTestName, testFunction,
  fakeDeviceInitParams, 'immersive-vr');
xr_session_promise_test(nonImmersiveTestName, testFunction,
  fakeDeviceInitParams, 'inline', { 'requiredFeatures': ['local'] });

</script>
