135 lines
4.8 KiB
HTML
135 lines
4.8 KiB
HTML
<!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>
|