From d93421443f7b7be8386ca55d126a85af14ec2aac Mon Sep 17 00:00:00 2001 From: Sorskoot Date: Thu, 8 Feb 2024 19:48:25 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20Merge=20PR=20#68549=20[WebXR]=20?= =?UTF-8?q?Add=20detectedPlanes,=20improve=20detectedMeshes,=20add=20tests?= =?UTF-8?q?=20by=20@sorskoot?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- types/webxr/index.d.ts | 64 ++++++++++++++++++++++++-------------- types/webxr/webxr-tests.ts | 28 +++++++++++++++++ 2 files changed, 69 insertions(+), 23 deletions(-) diff --git a/types/webxr/index.d.ts b/types/webxr/index.d.ts index 476fc8a54d7e89..d3ba524d625e35 100644 --- a/types/webxr/index.d.ts +++ b/types/webxr/index.d.ts @@ -329,15 +329,6 @@ interface XRFrame { * @param referenceSpace */ getViewerPose(referenceSpace: XRReferenceSpace): XRViewerPose | undefined; - - /** - * XRFrame is extended to contain detectedMeshes attribute - * which contains all meshes that are still tracked in the frame. - * - * The set is initially empty and will be populated by the update meshes algorithm. - * If this attribute is accessed when the frame is not active, the user agent MUST throw InvalidStateError. - */ - readonly detectedMeshes: XRMeshSet; } declare abstract class XRFrame implements XRFrame {} @@ -662,7 +653,22 @@ interface XRPlane { orientation: XRPlaneOrientation; planeSpace: XRSpace; polygon: DOMPointReadOnly[]; - lastChangedTime: number; + lastChangedTime: DOMHighResTimeStamp; + +} + +interface XRFrame { + /** + * XRFrame is extended to contain detectedPlanes attribute which contains + * all planes that are still tracked in the frame. + * + * The set is initially empty and will be populated by the update planes + * algorithm. If this attribute is accessed when the frame is not active, + * the user agent MUST throw InvalidStateError. + * + * @see https://immersive-web.github.io/real-world-geometry/plane-detection.html#plane-set + */ + readonly detectedPlanes?: XRPlaneSet; } declare abstract class XRPlane implements XRPlane {} @@ -678,22 +684,34 @@ interface XRMesh { semanticLabel?: string; } +interface XRFrame { + /** + * XRFrame is extended to contain detectedMeshes attribute + * which contains all meshes that are still tracked in the frame. + * + * The set is initially empty and will be populated by the update meshes algorithm. + * If this attribute is accessed when the frame is not active, the user agent + * MUST throw InvalidStateError. + * + * @see https://immersive-web.github.io/real-world-meshing/#mesh-set + */ + readonly detectedMeshes?: XRMeshSet; +} + declare abstract class XRMesh implements XRMesh {} interface XRSession { - // Legacy - updateWorldTrackingState?: (options: { - planeDetectionState?: { enabled: boolean } | undefined; - // eslint-disable-next-line @typescript-eslint/no-invalid-void-type - }) => void | undefined; -} - -interface XRFrame { - worldInformation?: - | { - detectedPlanes?: XRPlaneSet | undefined; - } - | undefined; + /** + * XRSession is extended to contain the initiateRoomCapture method which, + * if supported, will ask the XR Compositor to capture the current room layout. + * It is up to the XRCompositor if this will replace or augment the set of tracked planes. + * The user agent MAY also ignore this call, for instance if it doesn’t support a manual room + * capture more or if it determines that the room is already set up. + * The initiateRoomCapture method MUST only be able to be called once per XRSession. + * + * @see https://immersive-web.github.io/real-world-geometry/plane-detection.html#plane-set + */ + initiateRoomCapture?():Promise; } /** diff --git a/types/webxr/webxr-tests.ts b/types/webxr/webxr-tests.ts index 599f3f4fe2e9dd..fce874657af374 100644 --- a/types/webxr/webxr-tests.ts +++ b/types/webxr/webxr-tests.ts @@ -86,6 +86,12 @@ function assertNever(value: never) { const handle = session.requestAnimationFrame(loop); session.cancelAnimationFrame(handle); + if(session.initiateRoomCapture){ + session.initiateRoomCapture().then(()=>{ + console.log("Room capture initiated"); + }); + } + const renderFrame = (frame: XRFrame) => { const tf = new XRRigidTransform(startSpot, startRot); space = space.getOffsetReferenceSpace(tf); @@ -102,6 +108,28 @@ function assertNever(value: never) { const angularVelocity: DOMPointReadOnly | undefined = pose.angularVelocity; const linearVelocity: DOMPointReadOnly | undefined = pose.linearVelocity; } + + const detectedMeshes = frame.detectedMeshes; + detectedMeshes?.forEach((mesh:XRMesh) => { + const meshPose = frame.getPose(mesh.meshSpace, space); + if(meshPose){ + const transform = meshPose.transform; + } + console.log(mesh.lastChangedTime); + console.log(mesh.indices); + console.log(mesh.vertices); + console.log(mesh.lastChangedTime); + console.log(mesh.semanticLabel); + }); + + const detectedPlanes = frame.detectedPlanes; + detectedPlanes?.forEach((plane:XRPlane) => { + const planePose = frame.getPose(plane.planeSpace, space); + console.log(plane.lastChangedTime); + console.log(plane.orientation); + console.log(plane.polygon); + }); + }; navigator.xr.addEventListener("devicechange", (e: Event) => {