xrReferenceSpace_originOffset.https.html (4944B)
1 <!DOCTYPE html> 2 <script src="/resources/testharness.js"></script> 3 <script src="/resources/testharnessreport.js"></script> 4 <script src="resources/webxr_util.js"></script> 5 <script src="resources/webxr_test_constants.js"></script> 6 <script src="resources/webxr_test_asserts.js"></script> 7 8 <script> 9 let testName = "Updating XRReferenceSpace origin offset updates view and input matrices."; 10 11 const VIEW_OFFSET_WITH_ROTATION = { 12 position: [4, 3, 2], 13 orientation: [0, -0.7071, 0, 0.7071 ] 14 }; 15 16 const VIEWS_WITH_OFFSET = [{ 17 eye:"left", 18 projectionMatrix: VALID_PROJECTION_MATRIX, 19 viewOffset: VIEW_OFFSET_WITH_ROTATION, 20 resolution: VALID_RESOLUTION 21 }, { 22 eye:"right", 23 projectionMatrix: VALID_PROJECTION_MATRIX, 24 viewOffset: VIEW_OFFSET_WITH_ROTATION, 25 resolution: VALID_RESOLUTION 26 }]; 27 28 let fakeDeviceInitParams = { 29 supportsImmersive: true, 30 supportedModes: ["inline", "immersive-vr"], 31 viewerOrigin: VALID_POSE_TRANSFORM, 32 views: VIEWS_WITH_OFFSET, 33 supportedFeatures: ALL_FEATURES 34 }; 35 36 let testFunction = 37 (session, fakeDeviceController, t) => new Promise((resolve) => { 38 const GRIP_TRANSFORM_WITH_ROTATION = { 39 position: [1, 2, 3], 40 orientation: [0, 0.7071, 0, 0.7071] 41 }; 42 43 const POINTER_TRANSFORM_WITH_ROTATION = { 44 position: [0, 1, 4], 45 orientation: [-0.5, 0.5, 0.5, -0.5] 46 }; 47 48 let input_source = fakeDeviceController.simulateInputSourceConnection({ 49 handedness: "right", 50 targetRayMode: "tracked-pointer", 51 pointerOrigin: POINTER_TRANSFORM_WITH_ROTATION, 52 gripOrigin: GRIP_TRANSFORM_WITH_ROTATION, 53 profiles: [] 54 }); 55 56 const RADIANS_90D = Math.PI / 2; 57 58 const EXPECTED_VIEW_MATRIX_1 = [1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, -3, -4, 5, 1]; 59 const EXPECTED_GRIP_MATRIX_1 = [0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 2, 3, 1]; 60 const EXPECTED_RAY_MATRIX_1 = [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 2, 2, 1, 1]; 61 62 const EXPECTED_VIEW_MATRIX_2 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7, 1, 8, 1]; 63 const EXPECTED_GRIP_MATRIX_2 = [0, -1, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, -9, -2, -5, 1]; 64 const EXPECTED_RAY_MATRIX_2 = [0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -8, -4, -5, 1]; 65 66 const EXPECTED_VIEW_MATRIX_3 = [0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 12, 3, 8, 1]; 67 const EXPECTED_GRIP_MATRIX_3 = [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 5, -4, -14, 1]; 68 const EXPECTED_RAY_MATRIX_3 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5, -6, -13, 1]; 69 70 // Must have a reference space to get input poses. eye-level doesn't apply 71 // any transforms to the given matrix. 72 session.requestReferenceSpace('local').then( (referenceSpace) => { 73 function OnFrame(time, frame) { 74 let source = session.inputSources[0]; 75 76 function CheckState(referenceSpace, expected_view_matrix, expected_grip_matrix, expected_ray_matrix, prefix) { 77 t.step(() => { 78 let pose = frame.getViewerPose(referenceSpace); 79 let grip_pose = frame.getPose(source.gripSpace, referenceSpace); 80 let input_pose = frame.getPose(source.targetRaySpace, referenceSpace); 81 82 let view_matrix = pose.views[0].transform.inverse.matrix; 83 let grip_matrix = grip_pose.transform.matrix; 84 let ray_matrix = input_pose.transform.matrix; 85 86 assert_matrix_approx_equals(view_matrix, expected_view_matrix, prefix + " view matrix"); 87 assert_matrix_approx_equals(grip_matrix, expected_grip_matrix, prefix + " grip matrix"); 88 assert_matrix_approx_equals(ray_matrix, expected_ray_matrix, prefix + " ray matrix"); 89 }); 90 } 91 92 CheckState(referenceSpace, EXPECTED_VIEW_MATRIX_1, EXPECTED_GRIP_MATRIX_1, EXPECTED_RAY_MATRIX_1, "Initial"); 93 94 const new_position1 = { 95 x: 10, 96 y: -3, 97 z: 5, 98 }; 99 const new_orientation1 = { 100 x: Math.sin(RADIANS_90D / 2), 101 y: 0, 102 z: 0, 103 w: Math.cos(RADIANS_90D / 2), 104 }; 105 106 referenceSpace = referenceSpace.getOffsetReferenceSpace(new XRRigidTransform(new_position1, new_orientation1)); 107 CheckState(referenceSpace, EXPECTED_VIEW_MATRIX_2, EXPECTED_GRIP_MATRIX_2, EXPECTED_RAY_MATRIX_2, "First transform"); 108 109 const new_position2 = { 110 x: 5, 111 y: 2, 112 z: 0, 113 }; 114 const new_orientation2 = { 115 x: 0, 116 y: Math.sin(RADIANS_90D / 2), 117 z: 0, 118 w: Math.cos(RADIANS_90D / 2), 119 }; 120 121 referenceSpace = referenceSpace.getOffsetReferenceSpace(new XRRigidTransform(new_position2, new_orientation2)); 122 CheckState(referenceSpace, EXPECTED_VIEW_MATRIX_3, EXPECTED_GRIP_MATRIX_3, EXPECTED_RAY_MATRIX_3, "Second transform"); 123 124 resolve(); 125 } 126 127 // Can only request input poses in an xr frame. 128 requestSkipAnimationFrame(session, OnFrame); 129 }); 130 }); 131 132 xr_session_promise_test( 133 testName, testFunction, fakeDeviceInitParams, 'immersive-vr'); 134 135 </script>