Pārlūkot izejas kodu

headset impostor

Raanan Weber 5 gadi atpakaļ
vecāks
revīzija
ca889b0b46
1 mainītis faili ar 66 papildinājumiem un 7 dzēšanām
  1. 66 7
      src/XR/features/WebXRControllerPhysics.ts

+ 66 - 7
src/XR/features/WebXRControllerPhysics.ts

@@ -44,6 +44,33 @@ export class IWebXRControllerPhysicsOptions {
          */
          */
         restitution?: number;
         restitution?: number;
     };
     };
+
+    /**
+     * Should the headset get its own impostor
+     */
+    enableHeadsetImpostor?: boolean;
+
+    /**
+     * Optional parameters for the headset impostor
+     */
+    headsetImpostorParams?: {
+        /**
+         * The type of impostor to create. Default is sphere
+         */
+        impostorType: number;
+        /**
+         * the size of the impostor. Defaults to 10cm
+         */
+        impostorSize?: number | { width: number, height: number, depth: number };
+        /**
+         * Friction definitions
+         */
+        friction?: number;
+        /**
+         * Restitution
+         */
+        restitution?: number;
+    };
 }
 }
 
 
 /**
 /**
@@ -72,10 +99,14 @@ export class WebXRControllerPhysics extends WebXRAbstractFeature {
             impostorMesh?: AbstractMesh,
             impostorMesh?: AbstractMesh,
             impostor: PhysicsImpostor
             impostor: PhysicsImpostor
             oldPos?: Vector3;
             oldPos?: Vector3;
+            oldSpeed?: Vector3,
             oldRotation?: Quaternion;
             oldRotation?: Quaternion;
         }
         }
     } = {};
     } = {};
 
 
+    private _headsetImpostor?: PhysicsImpostor;
+    private _headsetMesh?: AbstractMesh;
+
     private _tmpVector: Vector3 = new Vector3();
     private _tmpVector: Vector3 = new Vector3();
     private _tmpQuaternion: Quaternion = new Quaternion();
     private _tmpQuaternion: Quaternion = new Quaternion();
 
 
@@ -122,6 +153,10 @@ export class WebXRControllerPhysics extends WebXRAbstractFeature {
         }
         }
     }
     }
 
 
+    public getHeadsetImpostor() {
+        return this._headsetImpostor;
+    }
+
     /**
     /**
      * attach this feature
      * attach this feature
      * Will usually be called by the features manager
      * Will usually be called by the features manager
@@ -144,6 +179,23 @@ export class WebXRControllerPhysics extends WebXRAbstractFeature {
             this._detachController(controller.uniqueId);
             this._detachController(controller.uniqueId);
         });
         });
 
 
+        if (this._options.enableHeadsetImpostor) {
+            const params = this._options.headsetImpostorParams || {
+                impostorType: PhysicsImpostor.SphereImpostor,
+                restitution: 0.8,
+                impostorSize: 0.3
+            };
+            const impostorSize = params.impostorSize || 0.3;
+            this._headsetMesh = SphereBuilder.CreateSphere('headset-mesh', {
+                diameterX: typeof impostorSize === 'number' ? impostorSize : impostorSize.width,
+                diameterY: typeof impostorSize === 'number' ? impostorSize : impostorSize.height,
+                diameterZ: typeof impostorSize === 'number' ? impostorSize : impostorSize.depth
+            });
+            this._headsetMesh.rotationQuaternion = new Quaternion();
+            this._headsetMesh.isVisible = false;
+            this._headsetImpostor = new PhysicsImpostor(this._headsetMesh, params.impostorType, { mass: 0, ...params });
+        }
+
         return true;
         return true;
     }
     }
 
 
@@ -162,6 +214,10 @@ export class WebXRControllerPhysics extends WebXRAbstractFeature {
             this._detachController(controllerId);
             this._detachController(controllerId);
         });
         });
 
 
+        if (this._headsetMesh) {
+            this._headsetMesh.dispose();
+        }
+
         return true;
         return true;
     }
     }
 
 
@@ -253,6 +309,10 @@ export class WebXRControllerPhysics extends WebXRAbstractFeature {
     protected _onXRFrame(_xrFrame: any): void {
     protected _onXRFrame(_xrFrame: any): void {
         this._delta = (this._xrSessionManager.currentTimestamp - this._lastTimestamp);
         this._delta = (this._xrSessionManager.currentTimestamp - this._lastTimestamp);
         this._lastTimestamp = this._xrSessionManager.currentTimestamp;
         this._lastTimestamp = this._xrSessionManager.currentTimestamp;
+        if (this._headsetMesh) {
+            this._headsetMesh.position.copyFrom(this._options.xrInput.xrCamera.position);
+            this._headsetMesh.rotationQuaternion!.copyFrom(this._options.xrInput.xrCamera.rotationQuaternion!);
+        }
         Object.keys(this._controllers).forEach((controllerId) => {
         Object.keys(this._controllers).forEach((controllerId) => {
             const controllerData = this._controllers[controllerId];
             const controllerData = this._controllers[controllerId];
             const controllerMesh = controllerData.xrController.grip || controllerData.xrController.pointer;
             const controllerMesh = controllerData.xrController.grip || controllerData.xrController.pointer;
@@ -260,14 +320,13 @@ export class WebXRControllerPhysics extends WebXRAbstractFeature {
             const comparedPosition = controllerData.oldPos || controllerData.impostorMesh!.position;
             const comparedPosition = controllerData.oldPos || controllerData.impostorMesh!.position;
             const comparedQuaternion = controllerData.oldRotation || controllerData.impostorMesh!.rotationQuaternion!;
             const comparedQuaternion = controllerData.oldRotation || controllerData.impostorMesh!.rotationQuaternion!;
 
 
-            if (!controllerMesh.position.equalsWithEpsilon(comparedPosition)) {
-                controllerMesh.position.subtractToRef(comparedPosition, this._tmpVector);
-                this._tmpVector.scaleInPlace(this._delta);
-                controllerData.impostor.setLinearVelocity(this._tmpVector);
-                if (this._debugMode) {
-                    console.log(this._tmpVector, 'linear');
-                }
+            controllerMesh.position.subtractToRef(comparedPosition, this._tmpVector);
+            this._tmpVector.scaleInPlace(this._delta);
+            controllerData.impostor.setLinearVelocity(this._tmpVector);
+            if (this._debugMode) {
+                console.log(this._tmpVector, 'linear');
             }
             }
+
             if (!comparedQuaternion.equalsWithEpsilon(controllerMesh.rotationQuaternion!)) {
             if (!comparedQuaternion.equalsWithEpsilon(controllerMesh.rotationQuaternion!)) {
                 // roughly based on this - https://www.gamedev.net/forums/topic/347752-quaternion-and-angular-velocity/
                 // roughly based on this - https://www.gamedev.net/forums/topic/347752-quaternion-and-angular-velocity/
                 comparedQuaternion.conjugateInPlace().multiplyToRef(controllerMesh.rotationQuaternion!, this._tmpQuaternion);
                 comparedQuaternion.conjugateInPlace().multiplyToRef(controllerMesh.rotationQuaternion!, this._tmpQuaternion);