Bladeren bron

adding initial version of the ar hit test feature

Raanan Weber 5 jaren geleden
bovenliggende
commit
fc19f186d8
3 gewijzigde bestanden met toevoegingen van 96 en 1 verwijderingen
  1. 1 0
      src/Cameras/XR/features/index.ts
  2. 92 0
      src/Cameras/XR/features/webXRARHitTest.ts
  3. 3 1
      src/Cameras/XR/index.ts

+ 1 - 0
src/Cameras/XR/features/index.ts

@@ -0,0 +1 @@
+export * from "./webXRARHitTest";

+ 92 - 0
src/Cameras/XR/features/webXRARHitTest.ts

@@ -0,0 +1,92 @@
+import { WebXRFeature, WebXRFeaturesManager } from '../webXRFeaturesManager';
+import { WebXRSessionManager } from '../webXRSessionManager';
+import { Observable } from '../../../Misc/observable';
+import { Vector3, Matrix } from '../../../Maths/math';
+
+const Name = "xr-hit-test";
+//register the plugin
+WebXRFeaturesManager.AddWebXRFeature(Name, (xrSessionManager, options) => {
+    return () => new WebXRHitTest(xrSessionManager, options);
+});
+
+export interface XRSession {
+
+}
+
+export interface WebXRHitTestOptions {
+    testOnSelect?: boolean;
+}
+
+export interface WebXRHitResult {
+
+}
+
+export class WebXRHitTest implements WebXRFeature {
+
+    public static readonly Name = Name;
+
+    public onHitTestResultObservable: Observable<WebXRHitResult> = new Observable();
+
+    constructor(private xrSessionManager: WebXRSessionManager, private options: WebXRHitTestOptions = {}) {
+
+    }
+
+    readonly name: string = "ar-hit-test";
+
+    private _onSelectEnabled = false;
+
+    attachAsync(): Promise<boolean> {
+        if (this.options.testOnSelect) {
+            this.xrSessionManager.session.addEventListener('select', this.onSelect, false);
+        } else {
+            // we are in XR space!
+            const origin = new Vector3(0, 0, 0);
+            const direction = new Vector3(0, 0, -1);
+            const mat = new Matrix();
+            this.xrSessionManager.onXRFrameObservable.add((frame) => {
+                let pose = frame.getViewerPose(this.xrSessionManager.referenceSpace);
+                if (!pose) {
+                    return;
+                }
+                Matrix.FromArrayToRef(pose.transform.matrix, 0, mat);
+                Vector3.TransformCoordinatesFromFloatsToRef(0, 0, 0, mat, origin);
+                Vector3.TransformCoordinatesFromFloatsToRef(0, 0, -1, mat, direction);
+                direction.subtractInPlace(origin);
+                direction.normalize();
+                let ray = new XRRay((<DOMPointReadOnly>{ x: origin.x, y: origin.y, z: origin.z, w: 0 }),
+                    (<DOMPointReadOnly>{ x: direction.x, y: direction.y, z: direction.z, w: 0 }));
+                this.xrSessionManager.session.requestHitTest(ray, this.xrSessionManager.referenceSpace).then((results) => {
+                    // convert to babylon world space and notify the matrices results
+                    this.onHitTestResultObservable.notifyObservers(results);
+                });
+            });
+        }
+
+        return Promise.resolve(true);
+    }
+    detachAsync(): Promise<boolean> {
+        // disable select
+        this._onSelectEnabled = false;
+        return Promise.resolve(true);
+    }
+
+    private onSelect = (event: XRInputSourceEvent) => {
+        if (!this._onSelectEnabled) {
+            return;
+        }
+        let targetRayPose = event.frame.getPose(event.inputSource.targetRaySpace, this.xrSessionManager.referenceSpace);
+        if (!targetRayPose) {
+            return;
+        }
+        let targetRay = new XRRay(targetRayPose.transform);
+        event.frame.session.requestHitTest(targetRay, this.xrSessionManager.referenceSpace).then((results) => {
+            this.onHitTestResultObservable.notifyObservers(results);
+        });
+    }
+
+    dispose(): void {
+        this.xrSessionManager.session.removeEventListener('select', this.onSelect);
+        this.onHitTestResultObservable.clear();
+    }
+
+}

+ 3 - 1
src/Cameras/XR/index.ts

@@ -9,4 +9,6 @@ export * from "./webXRController";
 export * from "./webXRManagedOutputCanvas";
 export * from "./webXRTypes";
 export * from "./webXRSessionManager";
-export * from "./webXRDefaultExperience";
+export * from "./webXRDefaultExperience";
+export * from "./webXRFeaturesManager";
+export * from "./features/index";