blob: c12743d4f9849457e38cd46fb79ba0fe000edd9f [file] [edit]
<!DOCTYPE html> <!-- webkit-test-runner [ SpatialPortalEnabled=true ModelElementEnabled=true ModelProcessEnabled=true allowTestOnlyIPC=true ] -->
<html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="../resources/ui-helper.js"></script>
<script src="../model-element/resources/model-utils.js"></script>
<script src="resources/spatial-portal-utils.js"></script>
<style>
.portal { spatial: portal; width: 40cm; height: 20cm; }
</style>
<body>
<script>
'use strict';
internals.disableModelLoadDelaysForTesting();
const centeredCube = "2x2x2-center.usdz";
const offsetCube = "2x2x2-at-100x50x200.usdz";
promise_test(async t => {
const portal = createPortal(t);
const model = appendModel(portal, centeredCube);
await model.ready;
const boxFit = await waitForPortalTransform(portal, portalTransformIsResolved, "initial bounding box fit");
portal.style.portalAction = "orbit";
const sphereFit = await waitForPortalTransform(portal, transform => transform && !portalTransformsApproxEqual(transform, boxFit), "bounding sphere fit after switching to orbit");
assert_true(sphereFit.m11 < boxFit.m11, `the bounding sphere scale is smaller than the bounding box scale (${sphereFit.m11} < ${boxFit.m11})`);
portal.style.portalAction = "none";
const restoredFit = await waitForPortalTransform(portal, transform => transform && !portalTransformsApproxEqual(transform, sphereFit), "bounding box fit after switching back to none");
assert_3d_matrix_approx_equals(restoredFit, boxFit);
}, `portal-action switches portal-transform: auto between the bounding box and bounding sphere fits`);
promise_test(async t => {
const portal = createPortal(t, { portalAction: "orbit" });
const centered = appendModel(portal, centeredCube);
await centered.ready;
const before = await waitForPortalTransform(portal, portalTransformIsResolved, "sphere fit with one model");
const offset = appendModel(portal, offsetCube);
await offset.ready;
const after = await waitForPortalTransform(portal, transform => transform && !portalTransformsApproxEqual(transform, before), "sphere fit with both models");
assert_equals(internals.numberOfHostedModelsInSpatialPortal(portal), 2, "the portal hosts both models");
assert_true(after.m11 < before.m11, `the merged bounding sphere is larger, so the fit scale shrinks (${after.m11} < ${before.m11})`);
}, `portal-action: orbit recomputes the fit against the merged bounding sphere when a model is added`);
promise_test(async t => {
const portal = createPortal(t, { portalTransform: "none" });
const model = appendModel(portal, centeredCube);
await model.ready;
const before = await waitForPortalTransform(portal, portalTransformIsResolved, "initial 1:1 mapping");
assert_true(portalTransformScaleIsUnit(before), "portal-transform: none yields a 1:1 CSS unit mapping");
portal.style.portalAction = "orbit";
await UIHelper.ensureStablePresentationUpdate();
// portal-transform: none opts out of fitting entirely, so orbit must not change the mapping.
const after = await waitForPortalTransform(portal, portalTransformIsResolved, "1:1 mapping after switching to orbit");
assert_true(portalTransformScaleIsUnit(after), "portal-transform: none still yields a 1:1 CSS unit mapping");
}, `portal-action: orbit does not fit the content when portal-transform is none`);
// Only a portal taking part in the gesture registers touch handlers and advertises a model element to
// the page, so the two follow portal-action together.
promise_test(async t => {
const before = internals.touchEventHandlerCount();
const portal = createPortal(t);
await UIHelper.ensureStablePresentationUpdate();
assert_equals(internals.touchEventHandlerCount(), before, "portal-action: none registers no touch handlers");
portal.style.portalAction = "orbit";
await UIHelper.ensureStablePresentationUpdate();
assert_greater_than(internals.touchEventHandlerCount(), before, "orbit registers touch handlers");
portal.style.portalAction = "none";
await UIHelper.ensureStablePresentationUpdate();
assert_equals(internals.touchEventHandlerCount(), before, "switching back to none removes them");
}, `portal-action drives the portal's gesture handling`);
promise_test(async t => {
const before = internals.touchEventHandlerCount();
const portal = createPortal(t, { portalAction: "orbit" });
await UIHelper.ensureStablePresentationUpdate();
assert_greater_than(internals.touchEventHandlerCount(), before, "orbit registers touch handlers");
portal.style.portalAction = "none";
await UIHelper.ensureStablePresentationUpdate();
portal.remove();
await UIHelper.ensureStablePresentationUpdate();
assert_equals(internals.touchEventHandlerCount(), before, "removing the portal removes them exactly once");
}, `portal-action: orbit removes its gesture handling once when the portal is removed`);
promise_test(async t => {
const before = internals.touchEventHandlerCount();
const portal = createPortal(t, { portalAction: "orbit" });
const model = appendModel(portal, centeredCube);
await model.ready;
const fit = await waitForPortalTransform(portal, portalTransformIsResolved, "initial bounding sphere fit");
const withOrbit = internals.touchEventHandlerCount();
assert_greater_than(withOrbit, before, "orbit registers touch handlers");
portal.style.display = "none";
await UIHelper.ensureStablePresentationUpdate();
assert_false(internals.establishesSpatialPortal(portal), "the element no longer establishes a portal");
assert_equals(internals.touchEventHandlerCount(), before, "its touch handlers are removed");
await waitForPortalTransform(portal, portalTransformIsCleared, "the resolved transform is cleared");
portal.style.display = "block";
await UIHelper.ensureStablePresentationUpdate();
assert_true(internals.establishesSpatialPortal(portal), "the element establishes a portal again");
assert_equals(internals.touchEventHandlerCount(), withOrbit, "its touch handlers are registered again");
const refit = await waitForPortalTransform(portal, portalTransformIsResolved, "bounding sphere fit once the box is back");
assert_3d_matrix_approx_equals(refit, fit);
}, `portal-action: orbit behavior is restored after toggling the display property off and back on`);
</script>
</body>
</html>