Jelajahi Sumber

Expose feature points in BabylonJS as a native extension.

Alex Tran 5 tahun lalu
induk
melakukan
8d29416c39

+ 7 - 0
src/LibDeclarations/webxr.nativeextensions.d.ts

@@ -0,0 +1,7 @@
+// This file contains native only extensions for WebXR  These APIs are not supported in the browser yet.
+// They are intended for use with either Babylon Native https://github.com/BabylonJS/BabylonNative or
+// Babylon React Native: https://github.com/BabylonJS/BabylonReactNative
+
+interface XRFrame {
+    featurePointCloud? : Array<number>;
+}

+ 150 - 0
src/XR/features/WebXRFeaturePointSystem.ts

@@ -0,0 +1,150 @@
+import { WebXRFeaturesManager, WebXRFeatureName } from "../webXRFeaturesManager";
+import { WebXRSessionManager } from "../webXRSessionManager";
+import { Observable } from "../../Misc/observable";
+import { Vector3 } from "../../Maths/math.vector";
+import { WebXRAbstractFeature } from "./WebXRAbstractFeature";
+
+/**
+ * A babylon interface for a WebXR feature point.
+ * Represents the position and confidence value of a given feature point.
+ */
+export interface IWebXRFeaturePoint {
+    /**
+     * Represents the position of the feature point in world space.
+     */
+    position : Vector3;
+    /**
+     * Represents the confidence value of the feature point in world space. 0 being least confident, and 1 being most confident.
+     */
+    confidenceValue : number;
+}
+
+/**
+ * Callback function type definition for GetPointCloud. If the user requests this goes and fetches the point cloud from.
+ */
+type GetPointCloud = () => IWebXRFeaturePoint[];
+
+/**
+ * The feature point is used to detect feature points from real world geometry.
+ * This feature is currently only supported on BabylonNative, and should not be used in the browser.
+ * The newly introduced API can be seen in webxr.nativeextensions.d.ts.
+ */
+export class WebXRFeaturePointSystem extends WebXRAbstractFeature {
+    private _enabled: boolean = false;
+    private _featurePoints: Array<IWebXRFeaturePoint> | null = null;
+
+    /**
+     * The module's name
+     */
+    public static readonly Name = WebXRFeatureName.FEATURE_POINTS;
+    /**
+     * The (Babylon) version of this module.
+     * This is an integer representing the implementation version.
+     * This number does not correspond to the WebXR specs version
+     */
+    public static readonly Version = 1;
+    /**
+     * Observers registered here will be executed whenever new feature points are available (on XRFrame while the session is tracking).
+     */
+    public onFeaturePointsAvailableObservable: Observable<GetPointCloud> = new Observable();
+    /**
+     * construct the feature point system
+     * @param _xrSessionManager an instance of xr Session manager
+     * @param _options configuration to use when constructing this feature
+     */
+    constructor(_xrSessionManager: WebXRSessionManager, _options: any = {}) {
+        super(_xrSessionManager);
+        if (this._xrSessionManager.session) {
+            this._init();
+        } else {
+            this._xrSessionManager.onXRSessionInit.addOnce(() => {
+                this._init();
+            });
+        }
+    }
+
+    /**
+     * detach this feature.
+     * Will usually be called by the features manager
+     *
+     * @returns true if successful.
+     */
+    public detach(): boolean {
+        if (!super.detach()) {
+            return false;
+        }
+
+        this._featurePoints = null;
+        return true;
+    }
+
+    /**
+     * Dispose this feature and all of the resources attached
+     */
+    public dispose(): void {
+        super.dispose();
+
+        this._featurePoints = null;
+        this.onFeaturePointsAvailableObservable.clear();
+    }
+
+    protected _onXRFrame(frame: XRFrame) {
+        if (!this.attached || !this._enabled || !frame) {
+            return;
+        }
+
+        if (!("featurePointCloud" in frame))
+        {
+            this._enabled = false;
+            this.detach();
+        }
+
+        this._featurePoints = null;
+
+        this.onFeaturePointsAvailableObservable.notifyObservers(() => {
+            if (this._featurePoints)
+            {
+                return this._featurePoints;
+            }
+
+            let featurePointRawData : number[] | undefined = frame.featurePointCloud;
+            if (!featurePointRawData) {
+                return new Array<IWebXRFeaturePoint>();
+            }
+            else {
+                let numberOfFeaturePoints : number = featurePointRawData.length / 4;
+                this._featurePoints = new Array<IWebXRFeaturePoint>(featurePointRawData.length / 4);
+                for (var i = 0; i < numberOfFeaturePoints; i++) {
+                    let rawIndex : number = i * 4;
+                    this._featurePoints[i] = {
+                        position: new Vector3(
+                             featurePointRawData[rawIndex],
+                             featurePointRawData[rawIndex + 1],
+                             featurePointRawData[rawIndex + 2]),
+                        confidenceValue: featurePointRawData[4]
+                        };
+                }
+
+                return this._featurePoints;
+            }
+         });
+    }
+
+    private _init() {
+        if (!this._xrSessionManager.session.updateWorldTrackingState) {
+            // fail silently
+            return;
+        }
+
+        this._enabled = true;
+    }
+}
+
+//register the plugin
+WebXRFeaturesManager.AddWebXRFeature(
+    WebXRFeaturePointSystem.Name,
+    (xrSessionManager, options) => {
+        return () => new WebXRFeaturePointSystem(xrSessionManager, options);
+    },
+    WebXRFeaturePointSystem.Version
+);

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

@@ -6,3 +6,4 @@ export * from "./WebXRControllerTeleportation";
 export * from "./WebXRControllerPointerSelection";
 export * from "./WebXRControllerPhysics";
 export * from "./WebXRHitTest";
+export * from "./WebXRFeaturePointSystem";

+ 4 - 0
src/XR/webXRFeaturesManager.ts

@@ -77,6 +77,10 @@ export class WebXRFeatureName {
      * The name of the teleportation feature
      */
     public static TELEPORTATION = "xr-controller-teleportation";
+    /**
+     * The name of the feature points feature.
+     */
+    public static FEATURE_POINTS = "xr-feature-points";
 }
 
 /**