xrReferenceSpace_originOffsetBounded.https.html (7554B)
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 10 const testName = "Updating XRBoundedReferenceSpace origin offset updates view, input matrices, and bounds geometry."; 11 12 const INITIAL_VIEW_OFFSET = { 13 position: [1, 2, 3], 14 orientation: [0,0,0,1] 15 }; 16 17 const VIEWS_WITH_OFFSET = [{ 18 eye:"left", 19 projectionMatrix: VALID_PROJECTION_MATRIX, 20 viewOffset: INITIAL_VIEW_OFFSET, 21 resolution: VALID_RESOLUTION 22 }, { 23 eye:"right", 24 projectionMatrix: VALID_PROJECTION_MATRIX, 25 viewOffset: INITIAL_VIEW_OFFSET, 26 resolution: VALID_RESOLUTION 27 }]; 28 29 const FLOOR_TRANSFORM = { 30 position: [-0.1, -0.2, -0.3], 31 orientation: [0, 0, 0, 1] 32 }; 33 34 const fakeDeviceInitParams = { 35 supportsImmersive: true, 36 supportedModes: ["inline", "immersive-vr"], 37 views: VIEWS_WITH_OFFSET, 38 viewerOrigin: IDENTITY_TRANSFORM, 39 floorOrigin: FLOOR_TRANSFORM, 40 supportedFeatures: ALL_FEATURES, 41 boundsCoordinates: [ 42 { x: 1, z: -1.5 }, 43 { x: 1, z: 1.5 }, 44 { x: -1, z: 1.5 }, 45 { x: -1, z: -1.5 } 46 ] 47 }; 48 49 function testFunction(session, fakeDeviceController, t) { 50 const INITIAL_GRIP_TRANSFORM = { 51 position: [1, 2, 3], 52 orientation: [0, 0, 0, 1] 53 }; 54 55 const LOCAL_POINTER_TRANSFORM = { 56 position: [1.01, 2.02, 3.03], 57 orientation: [0, 0, 0, 1] 58 } 59 60 let input_source = fakeDeviceController.simulateInputSourceConnection({ 61 handedness: "right", 62 targetRayMode: "tracked-pointer", 63 pointerOrigin: LOCAL_POINTER_TRANSFORM, 64 gripOrigin: INITIAL_GRIP_TRANSFORM, 65 profiles: [] 66 }); 67 68 return new Promise((resolve, reject) => { 69 session.requestReferenceSpace('bounded-floor').then((referenceSpace) => { 70 requestSkipAnimationFrame(session, (time, frame) => { 71 let input_source = session.inputSources[0]; 72 73 function CheckState( 74 reference_space, 75 expected_view_matrix, 76 expected_grip_matrix, 77 expected_ray_matrix, 78 expected_bounds_geometry 79 ) { 80 t.step(() => { 81 let pose = frame.getViewerPose(reference_space); 82 let grip_pose = frame.getPose(input_source.gripSpace, reference_space); 83 let input_pose = frame.getPose(input_source.targetRaySpace, reference_space); 84 85 let view_matrix = pose.views[0].transform.inverse.matrix; 86 let grip_matrix = grip_pose.transform.matrix; 87 let ray_matrix = input_pose.transform.matrix; 88 89 assert_matrix_approx_equals(view_matrix, expected_view_matrix); 90 assert_matrix_approx_equals(grip_matrix, expected_grip_matrix); 91 assert_matrix_approx_equals(ray_matrix, expected_ray_matrix); 92 93 assert_equals(reference_space.boundsGeometry.length, expected_bounds_geometry.length); 94 for (var i = 0; i < reference_space.boundsGeometry.length; ++i) { 95 assert_point_approx_equals(reference_space.boundsGeometry[i], expected_bounds_geometry[i]); 96 } 97 }); 98 } 99 100 const EXPECTED_VIEW_MATRIX_1 = [ 101 1, 0, 0, 0, 102 0, 1, 0, 0, 103 0, 0, 1, 0, 104 -1.1, -2.2, -3.3, 1, 105 ]; 106 const EXPECTED_GRIP_MATRIX_1 = [ 107 1, 0, 0, 0, 108 0, 1, 0, 0, 109 0, 0, 1, 0, 110 1.1, 2.2, 3.3, 1, 111 ]; 112 const EXPECTED_RAY_MATRIX_1 = [ 113 1, 0, 0, 0, 114 0, 1, 0, 0, 115 0, 0, 1, 0, 116 1.11, 2.22, 3.33, 1, 117 ]; 118 119 const EXPECTED_BOUNDS_GEOMETRY_1 = [ 120 {x: 1, y: 0, z: -1.5, w: 1}, 121 {x: 1, y: 0, z: 1.5, w: 1}, 122 {x: -1, y: 0, z: 1.5, w: 1}, 123 {x: -1, y: 0, z: -1.5, w: 1}, 124 ]; 125 126 // Check state after initialization 127 CheckState( 128 referenceSpace, 129 EXPECTED_VIEW_MATRIX_1, 130 EXPECTED_GRIP_MATRIX_1, 131 EXPECTED_RAY_MATRIX_1, 132 EXPECTED_BOUNDS_GEOMETRY_1 133 ); 134 135 const RADIANS_90D = Math.PI / 2; 136 137 // Perform arbitrary transformation to reference space originOffset 138 const new_position1 = { 139 x: 10, // Translate 10 units along the x-axis 140 y: -3, // Translate -3 units along the y-axis 141 z: 5, // Translate 5 units along the z-axis 142 }; 143 const new_orientation1 = { 144 x: Math.sin(RADIANS_90D / 2), // Rotate 90 degrees around the x-axis 145 y: 0, 146 z: 0, 147 w: Math.cos(RADIANS_90D / 2), 148 }; 149 referenceSpace = referenceSpace.getOffsetReferenceSpace(new XRRigidTransform(new_position1, new_orientation1)); 150 151 const EXPECTED_VIEW_MATRIX_2 = [ 152 1, 0, 0, 0, 153 0, 0, 1, 0, 154 0, -1, 0, 0, 155 8.9, -5.2, 1.7, 1, 156 ]; 157 const EXPECTED_GRIP_MATRIX_2 = [ 158 1, 0, 0, 0, 159 0, 0, -1, 0, 160 0, 1, 0, 0, 161 -8.9, -1.7, -5.2, 1, 162 ]; 163 const EXPECTED_RAY_MATRIX_2 = [ 164 1, 0, 0, 0, 165 0, 0, -1, 0, 166 0, 1, 0, 0, 167 -8.89, -1.67, -5.22, 1, 168 ]; 169 170 const EXPECTED_BOUNDS_GEOMETRY_2 = [ 171 {x: -9, y: -6.5, z: -3, w: 1}, 172 {x: -9, y: -3.5, z: -3, w: 1}, 173 {x: -11, y: -3.5, z: -3, w: 1}, 174 {x: -11, y: -6.5, z: -3, w: 1}, 175 ]; 176 177 // Check state after transformation 178 CheckState( 179 referenceSpace, 180 EXPECTED_VIEW_MATRIX_2, 181 EXPECTED_GRIP_MATRIX_2, 182 EXPECTED_RAY_MATRIX_2, 183 EXPECTED_BOUNDS_GEOMETRY_2 184 ); 185 186 // Perform arbitrary transformation to reference space originOffset 187 const new_position2 = { 188 x: 5, // Translate 5 units along the x-axis 189 y: 2, // Translate 2 units along the y-axis 190 z: 0, 191 }; 192 const new_orientation2 = { 193 x: 0, 194 y: Math.sin(RADIANS_90D / 2), // Rotate 90 degrees about the y-axis 195 z: 0, 196 w: Math.cos(RADIANS_90D / 2), 197 }; 198 referenceSpace = referenceSpace.getOffsetReferenceSpace(new XRRigidTransform(new_position2, new_orientation2)); 199 200 const EXPECTED_VIEW_MATRIX_3 = [ 201 0, 1, 0, 0, 202 0, 0, 1, 0, 203 1, 0, 0, 0, 204 13.9, -5.2, 3.7, 1, 205 ]; 206 const EXPECTED_GRIP_MATRIX_3 = [ 207 0, 0, 1, 0, 208 1, 0, 0, 0, 209 0, 1, 0, 0, 210 5.2, -3.7, -13.9, 1, 211 ]; 212 const EXPECTED_RAY_MATRIX_3 = [ 213 0, 0, 1, 0, 214 1, 0, 0, 0, 215 0, 1, 0, 0, 216 5.22, -3.67, -13.89, 1, 217 ]; 218 219 const EXPECTED_BOUNDS_GEOMETRY_3 = [ 220 {x: 3, y: -8.5, z: -14, w: 1}, 221 {x: 3, y: -5.5, z: -14, w: 1}, 222 {x: 3, y: -5.5, z: -16, w: 1}, 223 {x: 3, y: -8.5, z: -16, w: 1}, 224 ]; 225 226 // Check state after transformation 227 CheckState( 228 referenceSpace, 229 EXPECTED_VIEW_MATRIX_3, 230 EXPECTED_GRIP_MATRIX_3, 231 EXPECTED_RAY_MATRIX_3, 232 EXPECTED_BOUNDS_GEOMETRY_3 233 ); 234 235 resolve(); 236 }); 237 }); 238 }); 239 }; 240 241 xr_session_promise_test( 242 testName, testFunction, fakeDeviceInitParams, 'immersive-vr', { 'requiredFeatures': ['bounded-floor'] }); 243 244 </script>