summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/webxr/xrReferenceSpace_originOffset.https.html
blob: d93f696a2dafa5e92bb55a14c65d74bc0216bb56 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<!DOCTYPE html>
<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 = "Updating XRReferenceSpace origin offset updates view and input matrices.";

const VIEW_OFFSET_WITH_ROTATION = {
  position: [4, 3, 2],
  orientation: [0, -0.7071, 0, 0.7071 ]
};

const VIEWS_WITH_OFFSET = [{
  eye:"left",
  projectionMatrix: VALID_PROJECTION_MATRIX,
  viewOffset: VIEW_OFFSET_WITH_ROTATION,
  resolution: VALID_RESOLUTION
}, {
  eye:"right",
  projectionMatrix: VALID_PROJECTION_MATRIX,
  viewOffset: VIEW_OFFSET_WITH_ROTATION,
  resolution: VALID_RESOLUTION
}];

let fakeDeviceInitParams = {
  supportsImmersive: true,
  supportedModes: ["inline", "immersive-vr"],
  viewerOrigin: VALID_POSE_TRANSFORM,
  views: VIEWS_WITH_OFFSET,
  supportedFeatures: ALL_FEATURES
};

let testFunction =
  (session, fakeDeviceController, t) => new Promise((resolve) => {
    const GRIP_TRANSFORM_WITH_ROTATION = {
      position: [1, 2, 3],
      orientation: [0, 0.7071, 0, 0.7071]
    };

    const POINTER_TRANSFORM_WITH_ROTATION = {
      position: [0, 1, 4],
      orientation: [-0.5, 0.5, 0.5, -0.5]
    };

    let input_source = fakeDeviceController.simulateInputSourceConnection({
      handedness: "right",
      targetRayMode: "tracked-pointer",
      pointerOrigin: POINTER_TRANSFORM_WITH_ROTATION,
      gripOrigin: GRIP_TRANSFORM_WITH_ROTATION,
      profiles: []
    });

    const RADIANS_90D = Math.PI / 2;

    const EXPECTED_VIEW_MATRIX_1 = [1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, -3, -4, 5, 1];
    const EXPECTED_GRIP_MATRIX_1 = [0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 2, 3, 1];
    const EXPECTED_RAY_MATRIX_1 = [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 2, 2, 1, 1];

    const EXPECTED_VIEW_MATRIX_2 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7, 1, 8, 1];
    const EXPECTED_GRIP_MATRIX_2 = [0, -1, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, -9, -2, -5, 1];
    const EXPECTED_RAY_MATRIX_2 = [0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -8, -4, -5, 1];

    const EXPECTED_VIEW_MATRIX_3 = [0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 12, 3, 8, 1];
    const EXPECTED_GRIP_MATRIX_3 = [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 5, -4, -14, 1];
    const EXPECTED_RAY_MATRIX_3 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5, -6, -13, 1];

    // Must have a reference space to get input poses. eye-level doesn't apply
    // any transforms to the given matrix.
    session.requestReferenceSpace('local').then( (referenceSpace) => {
      function OnFrame(time, frame) {
        let source = session.inputSources[0];

        function CheckState(referenceSpace, expected_view_matrix, expected_grip_matrix, expected_ray_matrix, prefix) {
          t.step(() => {
            let pose = frame.getViewerPose(referenceSpace);
            let grip_pose = frame.getPose(source.gripSpace, referenceSpace);
            let input_pose = frame.getPose(source.targetRaySpace, referenceSpace);

            let view_matrix = pose.views[0].transform.inverse.matrix;
            let grip_matrix = grip_pose.transform.matrix;
            let ray_matrix = input_pose.transform.matrix;

            assert_matrix_approx_equals(view_matrix, expected_view_matrix, prefix + " view matrix");
            assert_matrix_approx_equals(grip_matrix, expected_grip_matrix, prefix + " grip matrix");
            assert_matrix_approx_equals(ray_matrix, expected_ray_matrix, prefix + " ray matrix");
          });
        }

        CheckState(referenceSpace, EXPECTED_VIEW_MATRIX_1, EXPECTED_GRIP_MATRIX_1, EXPECTED_RAY_MATRIX_1, "Initial");

        const new_position1 = {
          x: 10,
          y: -3,
          z: 5,
        };
        const new_orientation1 = {
          x: Math.sin(RADIANS_90D / 2),
          y: 0,
          z: 0,
          w: Math.cos(RADIANS_90D / 2),
        };

        referenceSpace = referenceSpace.getOffsetReferenceSpace(new XRRigidTransform(new_position1, new_orientation1));
        CheckState(referenceSpace, EXPECTED_VIEW_MATRIX_2, EXPECTED_GRIP_MATRIX_2, EXPECTED_RAY_MATRIX_2, "First transform");

        const new_position2 = {
          x: 5,
          y: 2,
          z: 0,
        };
        const new_orientation2 = {
          x: 0,
          y: Math.sin(RADIANS_90D / 2),
          z: 0,
          w: Math.cos(RADIANS_90D / 2),
        };

        referenceSpace = referenceSpace.getOffsetReferenceSpace(new XRRigidTransform(new_position2, new_orientation2));
        CheckState(referenceSpace, EXPECTED_VIEW_MATRIX_3, EXPECTED_GRIP_MATRIX_3, EXPECTED_RAY_MATRIX_3, "Second transform");

        resolve();
      }

      // Can only request input poses in an xr frame.
      requestSkipAnimationFrame(session, OnFrame);
    });
  });

xr_session_promise_test(
  testName, testFunction, fakeDeviceInitParams, 'immersive-vr');

</script>