瀏覽代碼

initial support for pointers

Raanan Weber 5 年之前
父節點
當前提交
c85a95f250
共有 1 個文件被更改,包括 127 次插入99 次删除
  1. 127 99
      src/XR/features/WebXRControllerTeleportation.ts

+ 127 - 99
src/XR/features/WebXRControllerTeleportation.ts

@@ -24,6 +24,7 @@ import { WebXRAbstractFeature } from './WebXRAbstractFeature';
 import { Color3 } from '../../Maths/math.color';
 import { Scene } from '../../scene';
 import { UtilityLayerRenderer } from '../../Rendering/utilityLayerRenderer';
+import { PointerEventTypes } from '../../Events/pointerEvents';
 
 /**
  * The options container for the teleportation module
@@ -405,116 +406,143 @@ export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {
             }
         };
         const controllerData = this._controllers[xrController.uniqueId];
-        // motion controller support
-        xrController.onMotionControllerInitObservable.addOnce(() => {
-            if (xrController.motionController) {
-                const movementController = xrController.motionController.getComponentOfType(WebXRControllerComponent.THUMBSTICK_TYPE) || xrController.motionController.getComponentOfType(WebXRControllerComponent.TOUCHPAD_TYPE);
+        if (controllerData.xrController.inputSource.targetRayMode === 'tracked-pointer') {
+            // motion controller support
+            xrController.onMotionControllerInitObservable.addOnce(() => {
+                if (xrController.motionController) {
+                    const movementController = xrController.motionController.getComponentOfType(WebXRControllerComponent.THUMBSTICK_TYPE) || xrController.motionController.getComponentOfType(WebXRControllerComponent.TOUCHPAD_TYPE);
                 if (!movementController || this._options.useMainComponentOnly) {
-                    // use trigger to move on long press
-                    const mainComponent = xrController.motionController.getMainComponent();
-                    if (!mainComponent) {
-                        return;
-                    }
-                    controllerData.onButtonChangedObserver = mainComponent.onButtonStateChangedObservable.add(() => {
-                        // did "pressed" changed?
-                        if (mainComponent.changes.pressed) {
-                            if (mainComponent.changes.pressed.current) {
-                                // simulate "forward" thumbstick push
+                        // use trigger to move on long press
+                        const mainComponent = xrController.motionController.getMainComponent();
+                        if (!mainComponent) {
+                            return;
+                        }
+                        controllerData.onButtonChangedObserver = mainComponent.onButtonStateChangedObservable.add(() => {
+                            // did "pressed" changed?
+                            if (mainComponent.changes.pressed) {
+                                if (mainComponent.changes.pressed.current) {
+                                    // simulate "forward" thumbstick push
+                                    controllerData.teleportationState.forward = true;
+                                    this._currentTeleportationControllerId = controllerData.xrController.uniqueId;
+                                    controllerData.teleportationState.baseRotation = this._options.xrInput.xrCamera.rotationQuaternion.toEulerAngles().y;
+                                    controllerData.teleportationState.currentRotation = 0;
+                                    const timeToSelect = this._options.timeToTeleport || 3000;
+                                    let timer = 0;
+                                    const observer = this._xrSessionManager.onXRFrameObservable.add(() => {
+                                        if (!mainComponent.pressed) {
+                                            this._xrSessionManager.onXRFrameObservable.remove(observer);
+                                            return;
+                                        }
+                                        timer += this._xrSessionManager.scene.getEngine().getDeltaTime();
+                                        if (timer >= timeToSelect && this._currentTeleportationControllerId === controllerData.xrController.uniqueId && controllerData.teleportationState.forward) {
+                                            this._teleportForward(xrController.uniqueId);
+                                        }
+
+                                        // failsafe
+                                        if (timer >= timeToSelect) {
+                                            this._xrSessionManager.onXRFrameObservable.remove(observer);
+                                        }
+                                    });
+                                } else {
+                                    controllerData.teleportationState.forward = false;
+                                    this._currentTeleportationControllerId = "";
+                                }
+                            }
+                        });
+                    } else {
+                        controllerData.onButtonChangedObserver = movementController.onButtonStateChangedObservable.add(() => {
+                            if (this._currentTeleportationControllerId === controllerData.xrController.uniqueId && controllerData.teleportationState.forward && !movementController.touched) {
+                                this._teleportForward(xrController.uniqueId);
+                            }
+                        });
+                        // use thumbstick (or touchpad if thumbstick not available)
+                        controllerData.onAxisChangedObserver = movementController.onAxisValueChangedObservable.add((axesData) => {
+                            if (axesData.y <= 0.7 && controllerData.teleportationState.backwards) {
+                                //if (this._currentTeleportationControllerId === controllerData.xrController.uniqueId) {
+                                controllerData.teleportationState.backwards = false;
+                                //this._currentTeleportationControllerId = "";
+                                //}
+                            }
+                            if (axesData.y > 0.7 && !controllerData.teleportationState.forward && this.backwardsMovementEnabled && !this.snapPointsOnly) {
+                                // teleport backwards
+                                if (!controllerData.teleportationState.backwards) {
+                                    controllerData.teleportationState.backwards = true;
+                                    // teleport backwards ONCE
+                                    this._tmpVector.set(0, 0, this.backwardsTeleportationDistance!);
+                                    this._tmpVector.rotateByQuaternionToRef(this._options.xrInput.xrCamera.rotationQuaternion!, this._tmpVector);
+                                    this._tmpVector.addInPlace(this._options.xrInput.xrCamera.position);
+                                    this._options.xrInput.xrCamera.position.subtractToRef(this._tmpVector, this._tmpVector);
+                                    this._tmpRay.origin.copyFrom(this._tmpVector);
+                                    this._tmpRay.direction.set(0, -1, 0);
+                                    let pick = this._xrSessionManager.scene.pickWithRay(this._tmpRay, (o) => {
+                                        return this._floorMeshes.indexOf(o) !== -1;
+                                    });
+
+                                    // pick must exist, but stay safe
+                                    if (pick && pick.pickedPoint) {
+                                        // Teleport the users feet to where they targeted
+                                        this._options.xrInput.xrCamera.position.addInPlace(pick.pickedPoint);
+                                    }
+                                }
+                            }
+                            if (axesData.y < -0.7 && !this._currentTeleportationControllerId && !controllerData.teleportationState.rotating) {
                                 controllerData.teleportationState.forward = true;
                                 this._currentTeleportationControllerId = controllerData.xrController.uniqueId;
                                 controllerData.teleportationState.baseRotation = this._options.xrInput.xrCamera.rotationQuaternion.toEulerAngles().y;
-                                controllerData.teleportationState.currentRotation = 0;
-                                const timeToSelect = this._options.timeToTeleport || 3000;
-                                let timer = 0;
-                                const observer = this._xrSessionManager.onXRFrameObservable.add(() => {
-                                    if (!mainComponent.pressed) {
-                                        this._xrSessionManager.onXRFrameObservable.remove(observer);
-                                        return;
+                            }
+                            if (axesData.x) {
+                                if (!controllerData.teleportationState.forward) {
+                                    if (!controllerData.teleportationState.rotating && Math.abs(axesData.x) > 0.7) {
+                                        // rotate in the right direction positive is right
+                                        controllerData.teleportationState.rotating = true;
+                                        const rotation = this.rotationAngle * (axesData.x > 0 ? 1 : -1);
+                                        this._options.xrInput.xrCamera.rotationQuaternion.multiplyInPlace(Quaternion.FromEulerAngles(0, rotation, 0));
                                     }
-                                    timer += this._xrSessionManager.scene.getEngine().getDeltaTime();
-                                    if (timer >= timeToSelect && this._currentTeleportationControllerId === controllerData.xrController.uniqueId && controllerData.teleportationState.forward) {
-                                        this._teleportForward(xrController.uniqueId);
+                                } else {
+                                    if (this._currentTeleportationControllerId === controllerData.xrController.uniqueId) {
+                                        // set the rotation of the forward movement
+                                        if (this.rotationEnabled) {
+                                            setTimeout(() => {
+                                                controllerData.teleportationState.currentRotation = Math.atan2(axesData.x, -axesData.y);
+                                            });
+                                        } else {
+                                            controllerData.teleportationState.currentRotation = 0;
+                                        }
                                     }
-
-                                    // failsafe
-                                    if (timer >= timeToSelect) {
-                                        this._xrSessionManager.onXRFrameObservable.remove(observer);
-                                    }
-                                });
+                                }
                             } else {
-                                controllerData.teleportationState.forward = false;
-                                this._currentTeleportationControllerId = "";
+                                controllerData.teleportationState.rotating = false;
                             }
-                        }
-                    });
-                } else {
-                    controllerData.onButtonChangedObserver = movementController.onButtonStateChangedObservable.add(() => {
-                        if (this._currentTeleportationControllerId === controllerData.xrController.uniqueId && controllerData.teleportationState.forward && !movementController.touched) {
-                            this._teleportForward(xrController.uniqueId);
-                        }
-                    });
-                    // use thumbstick (or touchpad if thumbstick not available)
-                    controllerData.onAxisChangedObserver = movementController.onAxisValueChangedObservable.add((axesData) => {
-                        if (axesData.y <= 0.7 && controllerData.teleportationState.backwards) {
-                            //if (this._currentTeleportationControllerId === controllerData.xrController.uniqueId) {
-                            controllerData.teleportationState.backwards = false;
-                            //this._currentTeleportationControllerId = "";
-                            //}
-                        }
-                        if (axesData.y > 0.7 && !controllerData.teleportationState.forward && this.backwardsMovementEnabled && !this.snapPointsOnly) {
-                            // teleport backwards
-                            if (!controllerData.teleportationState.backwards) {
-                                controllerData.teleportationState.backwards = true;
-                                // teleport backwards ONCE
-                                this._tmpVector.set(0, 0, this.backwardsTeleportationDistance!);
-                                this._tmpVector.rotateByQuaternionToRef(this._options.xrInput.xrCamera.rotationQuaternion!, this._tmpVector);
-                                this._tmpVector.addInPlace(this._options.xrInput.xrCamera.position);
-                                this._options.xrInput.xrCamera.position.subtractToRef(this._tmpVector, this._tmpVector);
-                                this._tmpRay.origin.copyFrom(this._tmpVector);
-                                this._tmpRay.direction.set(0, -1, 0);
-                                let pick = this._xrSessionManager.scene.pickWithRay(this._tmpRay, (o) => {
-                                    return this._floorMeshes.indexOf(o) !== -1;
-                                });
-
-                                // pick must exist, but stay safe
-                                if (pick && pick.pickedPoint) {
-                                    // Teleport the users feet to where they targeted
-                                    this._options.xrInput.xrCamera.position.addInPlace(pick.pickedPoint);
-                                }
+                        });
+                    }
+                }
+            });
+        } else {
+
+            this._xrSessionManager.scene.onPointerObservable.add((pointerInfo) => {
+                if (pointerInfo.type === PointerEventTypes.POINTERDOWN) {
+                    controllerData.teleportationState.forward = true;
+                        this._currentTeleportationControllerId = controllerData.xrController.uniqueId;
+                        controllerData.teleportationState.baseRotation = this._options.xrInput.xrCamera.rotationQuaternion.toEulerAngles().y;
+                        controllerData.teleportationState.currentRotation = 0;
+                        const timeToSelect = this._options.timeToTeleport || 3000;
+                        let timer = 0;
+                        const observer = this._xrSessionManager.onXRFrameObservable.add(() => {
+                            timer += this._xrSessionManager.scene.getEngine().getDeltaTime();
+                            if (timer >= timeToSelect && this._currentTeleportationControllerId === controllerData.xrController.uniqueId && controllerData.teleportationState.forward) {
+                                this._teleportForward(xrController.uniqueId);
                             }
-                        }
-                        if (axesData.y < -0.7 && !this._currentTeleportationControllerId && !controllerData.teleportationState.rotating) {
-                            controllerData.teleportationState.forward = true;
-                            this._currentTeleportationControllerId = controllerData.xrController.uniqueId;
-                            controllerData.teleportationState.baseRotation = this._options.xrInput.xrCamera.rotationQuaternion.toEulerAngles().y;
-                        }
-                        if (axesData.x) {
-                            if (!controllerData.teleportationState.forward) {
-                                if (!controllerData.teleportationState.rotating && Math.abs(axesData.x) > 0.7) {
-                                    // rotate in the right direction positive is right
-                                    controllerData.teleportationState.rotating = true;
-                                    const rotation = this.rotationAngle * (axesData.x > 0 ? 1 : -1);
-                                    this._options.xrInput.xrCamera.rotationQuaternion.multiplyInPlace(Quaternion.FromEulerAngles(0, rotation, 0));
-                                }
-                            } else {
-                                if (this._currentTeleportationControllerId === controllerData.xrController.uniqueId) {
-                                    // set the rotation of the forward movement
-                                    if (this.rotationEnabled) {
-                                        setTimeout(() => {
-                                            controllerData.teleportationState.currentRotation = Math.atan2(axesData.x, -axesData.y);
-                                        });
-                                    } else {
-                                        controllerData.teleportationState.currentRotation = 0;
-                                    }
-                                }
+
+                            if (timer >= timeToSelect) {
+                                this._xrSessionManager.onXRFrameObservable.remove(observer);
                             }
-                        } else {
-                            controllerData.teleportationState.rotating = false;
-                        }
-                    });
+                        });
+                } else if (pointerInfo.type === PointerEventTypes.POINTERUP) {
+                    controllerData.teleportationState.forward = false;
+                    this._currentTeleportationControllerId = "";
                 }
-            }
-        });
+            });
+        }
     }
 
     private _createDefaultTargetMesh() {