blob: fe5005dda04bbc5284d84accd411bedc062f8845 [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.
const testName = "Updating XRBoundedReferenceSpace origin offset updates view, input matrices, and bounds geometry.";
const fakeDeviceInitParams = { supportsImmersive: true };
const requestSessionModes = ['immersive-vr'];
function testFunction(session, t, fakeDeviceController) {
// Session must have a baseLayer or frame requests will be ignored.
session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) });
const INITIAL_VIEW_MATRIX = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
1, 2, 3, 1,
];
const INITIAL_GRIP_MATRIX = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
1, 2, 3, 1,
];
const LOCAL_POINTER_OFFSET = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0.01, 0.02, 0.03, 1,
];
const STAGE_TRANSFORM = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0.1, 0.2, 0.3, 1,
];
fakeDeviceController.setStageTransform(STAGE_TRANSFORM);
fakeDeviceController.setStageSize(2.0, 3.0);
fakeDeviceController.setXRPresentationFrameData(IDENTITY_MATRIX, [{
eye:"left",
projectionMatrix: VALID_PROJECTION_MATRIX,
viewMatrix: INITIAL_VIEW_MATRIX,
}, {
eye:"right",
projectionMatrix: VALID_PROJECTION_MATRIX,
viewMatrix: INITIAL_VIEW_MATRIX,
}]);
let input_source = new MockXRInputSource();
input_source.targetRayMode = "tracked-pointer";
input_source.handedness = "right";
input_source.grip = INITIAL_GRIP_MATRIX;
input_source.pointerOffset = LOCAL_POINTER_OFFSET;
fakeDeviceController.addInputSource(input_source);
return new Promise((resolve, reject) => {
session.requestAnimationFrame((time, frame) => {
let input_source = session.inputSources[0];
session.requestReferenceSpace('bounded-floor').then((referenceSpace) => {
function CheckState(
reference_space,
expected_view_matrix,
expected_grip_matrix,
expected_ray_matrix,
expected_bounds_geometry
) {
let pose = frame.getViewerPose(reference_space);
let grip_pose = frame.getPose(input_source.gripSpace, reference_space);
let input_pose = frame.getPose(input_source.targetRaySpace, reference_space);
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(expected_view_matrix, view_matrix);
assert_matrices_approx_equal(expected_grip_matrix, grip_matrix);
assert_matrices_approx_equal(expected_ray_matrix, ray_matrix);
assert_equals(reference_space.boundsGeometry.length, expected_bounds_geometry.length);
for (var i = 0; i < reference_space.boundsGeometry.length; ++i) {
assert_points_approx_equal(reference_space.boundsGeometry[i], expected_bounds_geometry[i]);
}
}
const EXPECTED_VIEW_MATRIX_1 = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
-0.1, -0.2, -0.3, 1,
];
const EXPECTED_GRIP_MATRIX_1 = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
1.1, 2.2, 3.3, 1,
];
const EXPECTED_RAY_MATRIX_1 = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
1.11, 2.22, 3.33, 1,
];
const EXPECTED_BOUNDS_GEOMETRY_1 = [
{x: 1, y: 0, z: -1.5, w: 1},
{x: 1, y: 0, z: 1.5, w: 1},
{x: -1, y: 0, z: 1.5, w: 1},
{x: -1, y: 0, z: -1.5, w: 1},
];
// Check state after initialization
CheckState(
referenceSpace,
EXPECTED_VIEW_MATRIX_1,
EXPECTED_GRIP_MATRIX_1,
EXPECTED_RAY_MATRIX_1,
EXPECTED_BOUNDS_GEOMETRY_1
);
const RADIANS_90D = Math.PI / 2;
// Perform arbitrary transformation to reference space originOffset
const new_position1 = {
x: 10, // Translate 10 units along the x-axis
y: -3, // Translate -3 units along the y-axis
z: 5, // Translate 5 units along the z-axis
};
const new_orientation1 = {
x: Math.sin(RADIANS_90D / 2), // Rotate 90 degrees around the x-axis
y: 0,
z: 0,
w: Math.cos(RADIANS_90D / 2),
};
referenceSpace = referenceSpace.getOffsetReferenceSpace(new XRRigidTransform(new_position1, new_orientation1));
const EXPECTED_VIEW_MATRIX_2 = [
1, 0, 0, 0,
0, 0, 1, 0,
0, -1, 0, 0,
9.9, -3.2, 4.7, 1,
];
const EXPECTED_GRIP_MATRIX_2 = [
1, 0, 0, 0,
0, 0, -1, 0,
0, 1, 0, 0,
-8.9, -1.7, -5.2, 1,
];
const EXPECTED_RAY_MATRIX_2 = [
1, 0, 0, 0,
0, 0, -1, 0,
0, 1, 0, 0,
-8.89, -1.67, -5.22, 1,
];
const EXPECTED_BOUNDS_GEOMETRY_2 = [
{x: -9, y: -6.5, z: -3, w: 1},
{x: -9, y: -3.5, z: -3, w: 1},
{x: -11, y: -3.5, z: -3, w: 1},
{x: -11, y: -6.5, z: -3, w: 1},
];
// Check state after transformation
CheckState(
referenceSpace,
EXPECTED_VIEW_MATRIX_2,
EXPECTED_GRIP_MATRIX_2,
EXPECTED_RAY_MATRIX_2,
EXPECTED_BOUNDS_GEOMETRY_2
);
// Perform arbitrary transformation to reference space originOffset
const new_position2 = {
x: 5, // Translate 5 units along the x-axis
y: 2, // Translate 2 units along the y-axis
z: 0,
};
const new_orientation2 = {
x: 0,
y: Math.sin(RADIANS_90D / 2), // Rotate 90 degrees about the y-axis
z: 0,
w: Math.cos(RADIANS_90D / 2),
};
referenceSpace = referenceSpace.getOffsetReferenceSpace(new XRRigidTransform(new_position2, new_orientation2));
const EXPECTED_VIEW_MATRIX_3 = [
0, 1, 0, 0,
0, 0, 1, 0,
1, 0, 0, 0,
14.9, -3.2, 6.7, 1,
];
const EXPECTED_GRIP_MATRIX_3 = [
0, 0, 1, 0,
1, 0, 0, 0,
0, 1, 0, 0,
5.2, -3.7, -13.9, 1,
];
const EXPECTED_RAY_MATRIX_3 = [
0, 0, 1, 0,
1, 0, 0, 0,
0, 1, 0, 0,
5.22, -3.67, -13.89, 1,
];
const EXPECTED_BOUNDS_GEOMETRY_3 = [
{x: 3, y: -8.5, z: -14, w: 1},
{x: 3, y: -5.5, z: -14, w: 1},
{x: 3, y: -5.5, z: -16, w: 1},
{x: 3, y: -8.5, z: -16, w: 1},
];
// Check state after transformation
CheckState(
referenceSpace,
EXPECTED_VIEW_MATRIX_3,
EXPECTED_GRIP_MATRIX_3,
EXPECTED_RAY_MATRIX_3,
EXPECTED_BOUNDS_GEOMETRY_3
);
resolve();
});
});
});
};
xr_session_promise_test(testFunction, fakeDeviceInitParams, requestSessionModes, testName);
</script>