blob: c6e971f10d0f73ba40ee9c9cdc27a07e2b77510d [file] [log] [blame]
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../external/wpt/webxr/resources/webxr_test_constants.js"></script>
<script src="../xr/resources/xr-internal-device-mocking.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
// Can't go in external WPT tests because this test uses MockXRInputSource which
// is not available there.
let testName = "Updating XRReferenceSpace origin offset updates view and input matrices.";
let fakeDeviceInitParams = { supportsImmersive: true };
let requestSessionOptions = ['immersive-vr'];
let testFunction =
(session, t, fakeDeviceController) => new Promise((resolve) => {
// Session must have a baseLayer or frame requests will be ignored.
session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) });
// Need to have a valid pose or input events don't process.
const VIEW_MATRIX_WITH_ROTATION = [
1, 0, 0, 0, // 1st col
0, 0, 1, 0, // 2nd col
0, -1, 0, 0, // 3rd col
4, 3, 2, 1 // 4th col
];
const GRIP_MATRIX_WITH_ROTATION = [
0, 0, -1, 0, // 1st col
0, 1, 0, 0, // 2nd col
1, 0, 0, 0, // 3rd col
1, 2, 3, 1 // 4th col
];
const POINTER_OFFSET_WITH_ROTATION = [
0, 1, 0, 0, // 1st col
-1, 0, 0, 0, // 2nd col
0, 0, 1, 0, // 3rd col
2, 0, 1, 1 // 4th col
]
fakeDeviceController.setXRPresentationFrameData(VALID_POSE_MATRIX, [{
eye:"left",
projectionMatrix: VALID_PROJECTION_MATRIX,
viewMatrix: VIEW_MATRIX_WITH_ROTATION
}, {
eye:"right",
projectionMatrix: VALID_PROJECTION_MATRIX,
viewMatrix: VIEW_MATRIX_WITH_ROTATION
}]);
let input_source = new MockXRInputSource();
input_source.targetRayMode = "tracked-pointer";
input_source.handedness = "right";
input_source.grip = GRIP_MATRIX_WITH_ROTATION;
input_source.pointerOffset = POINTER_OFFSET_WITH_ROTATION;
fakeDeviceController.addInputSource(input_source);
const EXPECTED_VIEW_MATRIX_1 = [0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, -1, -1, -1, 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 = [0.7419161200523376, 0.6434604525566101, -0.1884651929140091, 0, -0.1884651929140091, -0.06961867958307266, -0.9796091318130493, 0, -0.6434604525566101, 0.7623069882392883, 0.06961867958307266, 0, -4, 4, 9, 1];
const EXPECTED_GRIP_MATRIX_2 = [-0.6434604525566101, 0.06961867958307266, -0.7623069882392883, 0, 0.7419161200523376, -0.1884651929140091, -0.6434604525566101, 0, -0.1884651929140091, -0.9796091318130493, 0.06961867958307266, 0, 4.118846416473389, 8.01339340209961, -5.368484020233154, 1];
const EXPECTED_RAY_MATRIX_2 = [0.7419161200523376, -0.1884651929140091, -0.6434604525566101, 0, 0.6434604525566101, -0.06961867958307266, 0.7623069882392883, 0, -0.1884651929140091, -0.9796091318130493, 0.06961867958307266, 0, 2.643460512161255, 7.1730217933654785, -6.823479652404785, 1];
// Must have a reference space to get input poses. eye-level doesn't apply
// any transforms to the given matrix.
session.requestReferenceSpace({ type: "stationary", subtype: "eye-level" }).then( (referenceSpace) => {
function OnFrame(time, frame) {
let source = session.getInputSources()[0];
function CheckState(expected_view_matrix, expected_grip_matrix, expected_ray_matrix) {
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_matrices_approx_equal(view_matrix, expected_view_matrix);
assert_matrices_approx_equal(grip_matrix, expected_grip_matrix);
assert_matrices_approx_equal(ray_matrix, expected_ray_matrix);
}
CheckState(EXPECTED_VIEW_MATRIX_1, EXPECTED_GRIP_MATRIX_1, EXPECTED_RAY_MATRIX_1);
const new_position = {
x : 10,
y : -3,
z : 5
};
const degrees_45 = Math.PI / 4;
const rotation = Math.sin(degrees_45 / 2);
const new_orientation = {
x : rotation,
y : rotation * -1,
z : rotation * 3,
w : Math.cos(degrees_45 / 2)
};
referenceSpace.originOffset = new XRRigidTransform(new_position, new_orientation);
CheckState(EXPECTED_VIEW_MATRIX_2, EXPECTED_GRIP_MATRIX_2, EXPECTED_RAY_MATRIX_2);
resolve();
}
// Can only request input poses in an xr frame.
session.requestAnimationFrame(OnFrame);
});
});
xr_session_promise_test(
testFunction, fakeDeviceInitParams, requestSessionOptions, testName);
</script>