Преглед на файлове

Integrating collision checking into webXRHand

rickfromwork преди 4 години
родител
ревизия
a9311e5ef9
променени са 1 файла, в които са добавени 23 реда и са изтрити 3 реда
  1. 23 3
      src/XR/features/WebXRHandTracking.ts

+ 23 - 3
src/XR/features/WebXRHandTracking.ts

@@ -22,6 +22,7 @@ import { Engine } from "../../Engines/engine";
 import { Tools } from "../../Misc/tools";
 import { Axis } from "../../Maths/math.axis";
 import { TransformNode } from "../../Meshes/transformNode";
+import { Tags } from "../../Misc/tags";
 
 declare const XRHand: XRHand;
 
@@ -89,6 +90,10 @@ export interface IWebXRHandTrackingOptions {
             right: string[];
             left: string[];
         };
+        /**
+         * The scene that contains the 3D UI elements. Passing this in turns on near interactions with the index finger tip
+         */
+        sceneForNearInteraction?: Scene;
     };
 }
 
@@ -101,7 +106,7 @@ export const enum HandPart {
      */
     WRIST = "wrist",
     /**
-     * HandPart - The THumb
+     * HandPart - The thumb
      */
     THUMB = "thumb",
     /**
@@ -161,6 +166,7 @@ export class WebXRHand implements IDisposable {
      * @param _handMesh an optional hand mesh. if not provided, ours will be used
      * @param _rigMapping an optional rig mapping for the hand mesh. if not provided, ours will be used
      * @param disableDefaultHandMesh should the default mesh creation be disabled
+     * @param _nearInteractionMesh does a near interaction mesh exist for collision checking
      */
     constructor(
         /** the controller to which the hand correlates */
@@ -169,7 +175,8 @@ export class WebXRHand implements IDisposable {
         public readonly trackedMeshes: AbstractMesh[],
         private _handMesh?: AbstractMesh,
         private _rigMapping?: string[],
-        disableDefaultHandMesh?: boolean
+        disableDefaultHandMesh?: boolean,
+        private _nearInteractionMesh?: Nullable<AbstractMesh>
     ) {
         this.handPartsDefinition = this.generateHandPartsDefinition(xrController.inputSource.hand!);
         this._scene = trackedMeshes[0].getScene();
@@ -262,6 +269,12 @@ export class WebXRHand implements IDisposable {
                 }
             }
         });
+        // Update the invisible fingertip collidable
+        if (this._nearInteractionMesh) {
+            const indexTipIdx = this.handPartsDefinition[HandPart.INDEX][4];
+            const indexTipPose = this.trackedMeshes[indexTipIdx].position;
+            this._nearInteractionMesh.position.set(indexTipPose.x, indexTipPose.y, indexTipPose.z);
+        }
     }
 
     /**
@@ -534,10 +547,17 @@ export class WebXRHandTracking extends WebXRAbstractFeature {
             trackedMeshes.push(newInstance);
         }
 
+        let touchMesh: Nullable<AbstractMesh> = null;
+        if (this.options.jointMeshes?.sceneForNearInteraction) {
+            touchMesh = SphereBuilder.CreateSphere(`${xrController.uniqueId}-handJoint-indexCollidable`, {}, this.options.jointMeshes.sceneForNearInteraction);
+            touchMesh.isVisible = false;
+            Tags.AddTagsTo(touchMesh, "touchEnabled");
+        }
+
         const handedness = xrController.inputSource.handedness === "right" ? "right" : "left";
         const handMesh = this.options.jointMeshes?.handMeshes && this.options.jointMeshes?.handMeshes[handedness];
         const rigMapping = this.options.jointMeshes?.rigMapping && this.options.jointMeshes?.rigMapping[handedness];
-        const webxrHand = new WebXRHand(xrController, trackedMeshes, handMesh, rigMapping, this.options.jointMeshes?.disableDefaultHandMesh);
+        const webxrHand = new WebXRHand(xrController, trackedMeshes, handMesh, rigMapping, this.options.jointMeshes?.disableDefaultHandMesh, touchMesh);
 
         // get two new meshes
         this._hands[xrController.uniqueId] = {