ea5d4baeb913d1790af30946fb0a67fd781246264e1287fae98d4dec668cfd9e.json 94 KB

1
  1. {"ast":null,"code":"import { WebXRFeaturesManager, WebXRFeatureName } from \"../webXRFeaturesManager.js\";\nimport { Matrix, Vector3 } from \"../../Maths/math.vector.js\";\nimport { Color3 } from \"../../Maths/math.color.js\";\nimport { Axis } from \"../../Maths/math.axis.js\";\nimport { StandardMaterial } from \"../../Materials/standardMaterial.js\";\nimport { CreateCylinder } from \"../../Meshes/Builders/cylinderBuilder.js\";\nimport { CreateTorus } from \"../../Meshes/Builders/torusBuilder.js\";\nimport { Ray } from \"../../Culling/ray.js\";\nimport { PickingInfo } from \"../../Collisions/pickingInfo.js\";\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature.js\";\nimport { UtilityLayerRenderer } from \"../../Rendering/utilityLayerRenderer.js\";\nimport { Viewport } from \"../../Maths/math.viewport.js\";\nimport { Tools } from \"../../Misc/tools.js\";\n/**\n * A module that will enable pointer selection for motion controllers of XR Input Sources\n */\nexport class WebXRControllerPointerSelection extends WebXRAbstractFeature {\n /**\n * constructs a new background remover module\n * @param _xrSessionManager the session manager for this module\n * @param _options read-only options to be used in this module\n */\n constructor(_xrSessionManager, _options) {\n super(_xrSessionManager);\n this._options = _options;\n this._attachController = xrController => {\n if (this._controllers[xrController.uniqueId]) {\n // already attached\n return;\n }\n const {\n laserPointer,\n selectionMesh\n } = this._generateNewMeshPair(this._options.forceGripIfAvailable && xrController.grip ? xrController.grip : xrController.pointer);\n // get two new meshes\n this._controllers[xrController.uniqueId] = {\n xrController,\n laserPointer,\n selectionMesh,\n meshUnderPointer: null,\n pick: null,\n tmpRay: new Ray(new Vector3(), new Vector3()),\n disabledByNearInteraction: false,\n id: WebXRControllerPointerSelection._IdCounter++\n };\n if (this._attachedController) {\n if (!this._options.enablePointerSelectionOnAllControllers && this._options.preferredHandedness && xrController.inputSource.handedness === this._options.preferredHandedness) {\n this._attachedController = xrController.uniqueId;\n }\n } else {\n if (!this._options.enablePointerSelectionOnAllControllers) {\n this._attachedController = xrController.uniqueId;\n }\n }\n switch (xrController.inputSource.targetRayMode) {\n case \"tracked-pointer\":\n return this._attachTrackedPointerRayMode(xrController);\n case \"gaze\":\n return this._attachGazeMode(xrController);\n case \"screen\":\n case \"transient-pointer\":\n return this._attachScreenRayMode(xrController);\n }\n };\n this._controllers = {};\n this._tmpVectorForPickCompare = new Vector3();\n /**\n * Disable lighting on the laser pointer (so it will always be visible)\n */\n this.disablePointerLighting = true;\n /**\n * Disable lighting on the selection mesh (so it will always be visible)\n */\n this.disableSelectionMeshLighting = true;\n /**\n * Should the laser pointer be displayed\n */\n this.displayLaserPointer = true;\n /**\n * Should the selection mesh be displayed (The ring at the end of the laser pointer)\n */\n this.displaySelectionMesh = true;\n /**\n * This color will be set to the laser pointer when selection is triggered\n */\n this.laserPointerPickedColor = new Color3(0.9, 0.9, 0.9);\n /**\n * Default color of the laser pointer\n */\n this.laserPointerDefaultColor = new Color3(0.7, 0.7, 0.7);\n /**\n * default color of the selection ring\n */\n this.selectionMeshDefaultColor = new Color3(0.8, 0.8, 0.8);\n /**\n * This color will be applied to the selection ring when selection is triggered\n */\n this.selectionMeshPickedColor = new Color3(0.3, 0.3, 1.0);\n this._identityMatrix = Matrix.Identity();\n this._screenCoordinatesRef = Vector3.Zero();\n this._viewportRef = new Viewport(0, 0, 0, 0);\n this._scene = this._xrSessionManager.scene;\n // force look and pick mode if using WebXR on safari, assuming it is vision OS\n // Only if not explicitly set. If set to false, it will not be forced\n if (this._options.lookAndPickMode === undefined && (this._scene.getEngine()._badDesktopOS || this._scene.getEngine()._badOS)) {\n this._options.lookAndPickMode = true;\n }\n // look and pick mode extra state changes\n if (this._options.lookAndPickMode) {\n this._options.enablePointerSelectionOnAllControllers = true;\n this.displayLaserPointer = false;\n }\n }\n /**\n * attach this feature\n * Will usually be called by the features manager\n *\n * @returns true if successful.\n */\n attach() {\n if (!super.attach()) {\n return false;\n }\n this._options.xrInput.controllers.forEach(this._attachController);\n this._addNewAttachObserver(this._options.xrInput.onControllerAddedObservable, this._attachController, true);\n this._addNewAttachObserver(this._options.xrInput.onControllerRemovedObservable, controller => {\n // REMOVE the controller\n this._detachController(controller.uniqueId);\n }, true);\n this._scene.constantlyUpdateMeshUnderPointer = true;\n if (this._options.gazeCamera) {\n const webXRCamera = this._options.gazeCamera;\n const {\n laserPointer,\n selectionMesh\n } = this._generateNewMeshPair(webXRCamera);\n this._controllers[\"camera\"] = {\n webXRCamera,\n laserPointer,\n selectionMesh,\n meshUnderPointer: null,\n pick: null,\n tmpRay: new Ray(new Vector3(), new Vector3()),\n disabledByNearInteraction: false,\n id: WebXRControllerPointerSelection._IdCounter++\n };\n this._attachGazeMode();\n }\n return true;\n }\n /**\n * detach this feature.\n * Will usually be called by the features manager\n *\n * @returns true if successful.\n */\n detach() {\n if (!super.detach()) {\n return false;\n }\n Object.keys(this._controllers).forEach(controllerId => {\n this._detachController(controllerId);\n });\n return true;\n }\n /**\n * Will get the mesh under a specific pointer.\n * `scene.meshUnderPointer` will only return one mesh - either left or right.\n * @param controllerId the controllerId to check\n * @returns The mesh under pointer or null if no mesh is under the pointer\n */\n getMeshUnderPointer(controllerId) {\n if (this._controllers[controllerId]) {\n return this._controllers[controllerId].meshUnderPointer;\n } else {\n return null;\n }\n }\n /**\n * Get the xr controller that correlates to the pointer id in the pointer event\n *\n * @param id the pointer id to search for\n * @returns the controller that correlates to this id or null if not found\n */\n getXRControllerByPointerId(id) {\n const keys = Object.keys(this._controllers);\n for (let i = 0; i < keys.length; ++i) {\n if (this._controllers[keys[i]].id === id) {\n return this._controllers[keys[i]].xrController || null;\n }\n }\n return null;\n }\n /**\n * @internal\n */\n _getPointerSelectionDisabledByPointerId(id) {\n const keys = Object.keys(this._controllers);\n for (let i = 0; i < keys.length; ++i) {\n if (this._controllers[keys[i]].id === id) {\n return this._controllers[keys[i]].disabledByNearInteraction;\n }\n }\n return true;\n }\n /**\n * @internal\n */\n _setPointerSelectionDisabledByPointerId(id, state) {\n const keys = Object.keys(this._controllers);\n for (let i = 0; i < keys.length; ++i) {\n if (this._controllers[keys[i]].id === id) {\n this._controllers[keys[i]].disabledByNearInteraction = state;\n return;\n }\n }\n }\n _onXRFrame(_xrFrame) {\n Object.keys(this._controllers).forEach(id => {\n var _controllerData$xrCon;\n // look and pick mode\n // only do this for the selected pointer\n const controllerData = this._controllers[id];\n if (this._options.lookAndPickMode && ((_controllerData$xrCon = controllerData.xrController) === null || _controllerData$xrCon === void 0 ? void 0 : _controllerData$xrCon.inputSource.targetRayMode) !== \"transient-pointer\") {\n return;\n }\n if (!this._options.enablePointerSelectionOnAllControllers && id !== this._attachedController || controllerData.disabledByNearInteraction) {\n controllerData.selectionMesh.isVisible = false;\n controllerData.laserPointer.isVisible = false;\n controllerData.pick = null;\n return;\n }\n controllerData.laserPointer.isVisible = this.displayLaserPointer;\n let controllerGlobalPosition;\n // Every frame check collisions/input\n if (controllerData.xrController) {\n controllerGlobalPosition = this._options.forceGripIfAvailable && controllerData.xrController.grip ? controllerData.xrController.grip.position : controllerData.xrController.pointer.position;\n controllerData.xrController.getWorldPointerRayToRef(controllerData.tmpRay, this._options.forceGripIfAvailable);\n } else if (controllerData.webXRCamera) {\n controllerGlobalPosition = controllerData.webXRCamera.position;\n controllerData.webXRCamera.getForwardRayToRef(controllerData.tmpRay);\n } else {\n return;\n }\n if (this._options.maxPointerDistance) {\n controllerData.tmpRay.length = this._options.maxPointerDistance;\n }\n // update pointerX and pointerY of the scene. Only if the flag is set to true!\n if (!this._options.disableScenePointerVectorUpdate && controllerGlobalPosition) {\n const scene = this._xrSessionManager.scene;\n const camera = this._options.xrInput.xrCamera;\n if (camera) {\n camera.viewport.toGlobalToRef(scene.getEngine().getRenderWidth() / camera.rigCameras.length, scene.getEngine().getRenderHeight(), this._viewportRef);\n Vector3.ProjectToRef(controllerGlobalPosition, this._identityMatrix, camera.getTransformationMatrix(), this._viewportRef, this._screenCoordinatesRef);\n // stay safe\n if (typeof this._screenCoordinatesRef.x === \"number\" && typeof this._screenCoordinatesRef.y === \"number\" && !isNaN(this._screenCoordinatesRef.x) && !isNaN(this._screenCoordinatesRef.y) && this._screenCoordinatesRef.x !== Infinity && this._screenCoordinatesRef.y !== Infinity) {\n scene.pointerX = this._screenCoordinatesRef.x;\n scene.pointerY = this._screenCoordinatesRef.y;\n controllerData.screenCoordinates = {\n x: this._screenCoordinatesRef.x,\n y: this._screenCoordinatesRef.y\n };\n }\n }\n }\n let utilityScenePick = null;\n if (this._utilityLayerScene) {\n utilityScenePick = this._utilityLayerScene.pickWithRay(controllerData.tmpRay, this._utilityLayerScene.pointerMovePredicate || this.raySelectionPredicate);\n }\n const originalScenePick = this._scene.pickWithRay(controllerData.tmpRay, this._scene.pointerMovePredicate || this.raySelectionPredicate);\n if (!utilityScenePick || !utilityScenePick.hit) {\n // No hit in utility scene\n controllerData.pick = originalScenePick;\n } else if (!originalScenePick || !originalScenePick.hit) {\n // No hit in original scene\n controllerData.pick = utilityScenePick;\n } else if (utilityScenePick.distance < originalScenePick.distance) {\n // Hit is closer in utility scene\n controllerData.pick = utilityScenePick;\n } else {\n // Hit is closer in original scene\n controllerData.pick = originalScenePick;\n }\n if (controllerData.pick && controllerData.xrController) {\n controllerData.pick.aimTransform = controllerData.xrController.pointer;\n controllerData.pick.gripTransform = controllerData.xrController.grip || null;\n controllerData.pick.originMesh = controllerData.xrController.pointer;\n }\n const pick = controllerData.pick;\n if (pick && pick.pickedPoint && pick.hit) {\n // Update laser state\n this._updatePointerDistance(controllerData.laserPointer, pick.distance);\n // Update cursor state\n controllerData.selectionMesh.position.copyFrom(pick.pickedPoint);\n controllerData.selectionMesh.scaling.x = Math.sqrt(pick.distance);\n controllerData.selectionMesh.scaling.y = Math.sqrt(pick.distance);\n controllerData.selectionMesh.scaling.z = Math.sqrt(pick.distance);\n // To avoid z-fighting\n const pickNormal = this._convertNormalToDirectionOfRay(pick.getNormal(true), controllerData.tmpRay);\n const deltaFighting = 0.001;\n controllerData.selectionMesh.position.copyFrom(pick.pickedPoint);\n if (pickNormal) {\n const axis1 = Vector3.Cross(Axis.Y, pickNormal);\n const axis2 = Vector3.Cross(pickNormal, axis1);\n Vector3.RotationFromAxisToRef(axis2, pickNormal, axis1, controllerData.selectionMesh.rotation);\n controllerData.selectionMesh.position.addInPlace(pickNormal.scale(deltaFighting));\n }\n controllerData.selectionMesh.isVisible = this.displaySelectionMesh;\n controllerData.meshUnderPointer = pick.pickedMesh;\n } else {\n controllerData.selectionMesh.isVisible = false;\n this._updatePointerDistance(controllerData.laserPointer, 1);\n controllerData.meshUnderPointer = null;\n }\n });\n }\n get _utilityLayerScene() {\n return this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene;\n }\n _attachGazeMode(xrController) {\n const controllerData = this._controllers[xrController && xrController.uniqueId || \"camera\"];\n // attached when touched, detaches when raised\n const timeToSelect = this._options.timeToSelect || 3000;\n const sceneToRenderTo = this._options.useUtilityLayer ? this._utilityLayerScene : this._scene;\n let oldPick = new PickingInfo();\n const discMesh = CreateTorus(\"selection\", {\n diameter: 0.0035 * 15,\n thickness: 0.0025 * 6,\n tessellation: 20\n }, sceneToRenderTo);\n discMesh.isVisible = false;\n discMesh.isPickable = false;\n discMesh.parent = controllerData.selectionMesh;\n let timer = 0;\n let downTriggered = false;\n const pointerEventInit = {\n pointerId: controllerData.id,\n pointerType: \"xr\"\n };\n controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {\n if (!controllerData.pick) {\n return;\n }\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n controllerData.laserPointer.material.alpha = 0;\n discMesh.isVisible = false;\n if (controllerData.pick.hit) {\n if (!this._pickingMoved(oldPick, controllerData.pick)) {\n if (timer > timeToSelect / 10) {\n discMesh.isVisible = true;\n }\n timer += this._scene.getEngine().getDeltaTime();\n if (timer >= timeToSelect) {\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\n // this pointerdown event is not setting the controllerData.pointerDownTriggered to avoid a pointerUp event when this feature is detached\n downTriggered = true;\n // pointer up right after down, if disable on touch out\n if (this._options.disablePointerUpOnTouchOut) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n }\n discMesh.isVisible = false;\n } else {\n const scaleFactor = 1 - timer / timeToSelect;\n discMesh.scaling.set(scaleFactor, scaleFactor, scaleFactor);\n }\n } else {\n if (downTriggered) {\n if (!this._options.disablePointerUpOnTouchOut) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n }\n }\n downTriggered = false;\n timer = 0;\n }\n } else {\n downTriggered = false;\n timer = 0;\n }\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\n oldPick = controllerData.pick;\n });\n if (this._options.renderingGroupId !== undefined) {\n discMesh.renderingGroupId = this._options.renderingGroupId;\n }\n if (xrController) {\n xrController.onDisposeObservable.addOnce(() => {\n if (controllerData.pick && !this._options.disablePointerUpOnTouchOut && downTriggered) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n controllerData.finalPointerUpTriggered = true;\n }\n discMesh.dispose();\n });\n }\n }\n _attachScreenRayMode(xrController) {\n const controllerData = this._controllers[xrController.uniqueId];\n let downTriggered = false;\n const pointerEventInit = {\n pointerId: controllerData.id,\n pointerType: \"xr\"\n };\n controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n if (!controllerData.pick || this._options.disablePointerUpOnTouchOut && downTriggered) {\n return;\n }\n if (!downTriggered) {\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\n controllerData.pointerDownTriggered = true;\n downTriggered = true;\n if (this._options.disablePointerUpOnTouchOut) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n }\n } else {\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\n }\n });\n xrController.onDisposeObservable.addOnce(() => {\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n this._xrSessionManager.runInXRFrame(() => {\n if (controllerData.pick && !controllerData.finalPointerUpTriggered && downTriggered && !this._options.disablePointerUpOnTouchOut) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n controllerData.finalPointerUpTriggered = true;\n }\n });\n });\n }\n _attachTrackedPointerRayMode(xrController) {\n const controllerData = this._controllers[xrController.uniqueId];\n if (this._options.forceGazeMode) {\n return this._attachGazeMode(xrController);\n }\n const pointerEventInit = {\n pointerId: controllerData.id,\n pointerType: \"xr\"\n };\n controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {\n controllerData.laserPointer.material.disableLighting = this.disablePointerLighting;\n controllerData.selectionMesh.material.disableLighting = this.disableSelectionMeshLighting;\n if (controllerData.pick) {\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\n }\n });\n if (xrController.inputSource.gamepad) {\n const init = motionController => {\n if (this._options.overrideButtonId) {\n controllerData.selectionComponent = motionController.getComponent(this._options.overrideButtonId);\n }\n if (!controllerData.selectionComponent) {\n controllerData.selectionComponent = motionController.getMainComponent();\n }\n controllerData.onButtonChangedObserver = controllerData.selectionComponent.onButtonStateChangedObservable.add(component => {\n if (component.changes.pressed) {\n const pressed = component.changes.pressed.current;\n if (controllerData.pick) {\n if (this._options.enablePointerSelectionOnAllControllers || xrController.uniqueId === this._attachedController) {\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n if (pressed) {\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\n controllerData.pointerDownTriggered = true;\n controllerData.selectionMesh.material.emissiveColor = this.selectionMeshPickedColor;\n controllerData.laserPointer.material.emissiveColor = this.laserPointerPickedColor;\n } else {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n controllerData.selectionMesh.material.emissiveColor = this.selectionMeshDefaultColor;\n controllerData.laserPointer.material.emissiveColor = this.laserPointerDefaultColor;\n }\n }\n } else {\n if (pressed && !this._options.enablePointerSelectionOnAllControllers && !this._options.disableSwitchOnClick) {\n // force a pointer up if switching controllers\n // get the controller that was attached before\n const prevController = this._controllers[this._attachedController];\n if (prevController && prevController.pointerDownTriggered && !prevController.finalPointerUpTriggered) {\n this._augmentPointerInit(pointerEventInit, prevController.id, prevController.screenCoordinates);\n this._scene.simulatePointerUp(new PickingInfo(), {\n pointerId: prevController.id,\n pointerType: \"xr\"\n });\n prevController.finalPointerUpTriggered = true;\n }\n this._attachedController = xrController.uniqueId;\n }\n }\n }\n });\n };\n if (xrController.motionController) {\n init(xrController.motionController);\n } else {\n xrController.onMotionControllerInitObservable.add(init);\n }\n } else {\n // use the select and squeeze events\n const selectStartListener = event => {\n this._xrSessionManager.onXRFrameObservable.addOnce(() => {\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick) {\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\n controllerData.pointerDownTriggered = true;\n controllerData.selectionMesh.material.emissiveColor = this.selectionMeshPickedColor;\n controllerData.laserPointer.material.emissiveColor = this.laserPointerPickedColor;\n }\n });\n };\n const selectEndListener = event => {\n this._xrSessionManager.onXRFrameObservable.addOnce(() => {\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n controllerData.selectionMesh.material.emissiveColor = this.selectionMeshDefaultColor;\n controllerData.laserPointer.material.emissiveColor = this.laserPointerDefaultColor;\n }\n });\n };\n controllerData.eventListeners = {\n selectend: selectEndListener,\n selectstart: selectStartListener\n };\n this._xrSessionManager.session.addEventListener(\"selectstart\", selectStartListener);\n this._xrSessionManager.session.addEventListener(\"selectend\", selectEndListener);\n }\n }\n _convertNormalToDirectionOfRay(normal, ray) {\n if (normal) {\n const angle = Math.acos(Vector3.Dot(normal, ray.direction));\n if (angle < Math.PI / 2) {\n normal.scaleInPlace(-1);\n }\n }\n return normal;\n }\n _detachController(xrControllerUniqueId) {\n const controllerData = this._controllers[xrControllerUniqueId];\n if (!controllerData) {\n return;\n }\n if (controllerData.selectionComponent) {\n if (controllerData.onButtonChangedObserver) {\n controllerData.selectionComponent.onButtonStateChangedObservable.remove(controllerData.onButtonChangedObserver);\n }\n }\n if (controllerData.onFrameObserver) {\n this._xrSessionManager.onXRFrameObservable.remove(controllerData.onFrameObserver);\n }\n if (controllerData.eventListeners) {\n Object.keys(controllerData.eventListeners).forEach(eventName => {\n const func = controllerData.eventListeners && controllerData.eventListeners[eventName];\n if (func) {\n // For future reference - this is an issue in the WebXR typings.\n this._xrSessionManager.session.removeEventListener(eventName, func);\n }\n });\n }\n if (!controllerData.finalPointerUpTriggered && controllerData.pointerDownTriggered) {\n // Stay safe and fire a pointerup, in case it wasn't already triggered\n const pointerEventInit = {\n pointerId: controllerData.id,\n pointerType: \"xr\"\n };\n this._xrSessionManager.runInXRFrame(() => {\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n this._scene.simulatePointerUp(controllerData.pick || new PickingInfo(), pointerEventInit);\n controllerData.finalPointerUpTriggered = true;\n });\n }\n this._xrSessionManager.scene.onBeforeRenderObservable.addOnce(() => {\n try {\n controllerData.selectionMesh.dispose();\n controllerData.laserPointer.dispose();\n // remove from the map\n delete this._controllers[xrControllerUniqueId];\n if (this._attachedController === xrControllerUniqueId) {\n // check for other controllers\n const keys = Object.keys(this._controllers);\n if (keys.length) {\n this._attachedController = keys[0];\n } else {\n this._attachedController = \"\";\n }\n }\n } catch (e) {\n Tools.Warn(\"controller already detached.\");\n }\n });\n }\n _generateNewMeshPair(meshParent) {\n const sceneToRenderTo = this._options.useUtilityLayer ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene : this._scene;\n const laserPointer = this._options.customLasterPointerMeshGenerator ? this._options.customLasterPointerMeshGenerator() : CreateCylinder(\"laserPointer\", {\n height: 1,\n diameterTop: 0.0002,\n diameterBottom: 0.004,\n tessellation: 20,\n subdivisions: 1\n }, sceneToRenderTo);\n laserPointer.parent = meshParent;\n const laserPointerMaterial = new StandardMaterial(\"laserPointerMat\", sceneToRenderTo);\n laserPointerMaterial.emissiveColor = this.laserPointerDefaultColor;\n laserPointerMaterial.alpha = 0.7;\n laserPointer.material = laserPointerMaterial;\n laserPointer.rotation.x = Math.PI / 2;\n this._updatePointerDistance(laserPointer, 1);\n laserPointer.isPickable = false;\n laserPointer.isVisible = false;\n // Create a gaze tracker for the XR controller\n const selectionMesh = this._options.customSelectionMeshGenerator ? this._options.customSelectionMeshGenerator() : CreateTorus(\"gazeTracker\", {\n diameter: 0.0035 * 3,\n thickness: 0.0025 * 3,\n tessellation: 20\n }, sceneToRenderTo);\n selectionMesh.bakeCurrentTransformIntoVertices();\n selectionMesh.isPickable = false;\n selectionMesh.isVisible = false;\n const targetMat = new StandardMaterial(\"targetMat\", sceneToRenderTo);\n targetMat.specularColor = Color3.Black();\n targetMat.emissiveColor = this.selectionMeshDefaultColor;\n targetMat.backFaceCulling = false;\n selectionMesh.material = targetMat;\n if (this._options.renderingGroupId !== undefined) {\n laserPointer.renderingGroupId = this._options.renderingGroupId;\n selectionMesh.renderingGroupId = this._options.renderingGroupId;\n }\n return {\n laserPointer,\n selectionMesh\n };\n }\n _pickingMoved(oldPick, newPick) {\n var _oldPick$pickedPoint;\n if (!oldPick.hit || !newPick.hit) {\n return true;\n }\n if (!oldPick.pickedMesh || !oldPick.pickedPoint || !newPick.pickedMesh || !newPick.pickedPoint) {\n return true;\n }\n if (oldPick.pickedMesh !== newPick.pickedMesh) {\n return true;\n }\n (_oldPick$pickedPoint = oldPick.pickedPoint) === null || _oldPick$pickedPoint === void 0 || _oldPick$pickedPoint.subtractToRef(newPick.pickedPoint, this._tmpVectorForPickCompare);\n this._tmpVectorForPickCompare.set(Math.abs(this._tmpVectorForPickCompare.x), Math.abs(this._tmpVectorForPickCompare.y), Math.abs(this._tmpVectorForPickCompare.z));\n const delta = (this._options.gazeModePointerMovedFactor || 1) * 0.01 * newPick.distance;\n const length = this._tmpVectorForPickCompare.length();\n if (length > delta) {\n return true;\n }\n return false;\n }\n _updatePointerDistance(_laserPointer, distance = 100) {\n _laserPointer.scaling.y = distance;\n // a bit of distance from the controller\n if (this._scene.useRightHandedSystem) {\n distance *= -1;\n }\n _laserPointer.position.z = distance / 2 + 0.05;\n }\n _augmentPointerInit(pointerEventInit, id, screenCoordinates) {\n pointerEventInit.pointerId = id;\n pointerEventInit.pointerType = \"xr\";\n if (screenCoordinates) {\n pointerEventInit.screenX = screenCoordinates.x;\n pointerEventInit.screenY = screenCoordinates.y;\n }\n }\n /** @internal */\n get lasterPointerDefaultColor() {\n // here due to a typo\n return this.laserPointerDefaultColor;\n }\n}\nWebXRControllerPointerSelection._IdCounter = 200;\n/**\n * The module's name\n */\nWebXRControllerPointerSelection.Name = WebXRFeatureName.POINTER_SELECTION;\n/**\n * The (Babylon) version of this module.\n * This is an integer representing the implementation version.\n * This number does not correspond to the WebXR specs version\n */\nWebXRControllerPointerSelection.Version = 1;\n//register the plugin\nWebXRFeaturesManager.AddWebXRFeature(WebXRControllerPointerSelection.Name, (xrSessionManager, options) => {\n return () => new WebXRControllerPointerSelection(xrSessionManager, options);\n}, WebXRControllerPointerSelection.Version, true);","map":{"version":3,"names":["WebXRFeaturesManager","WebXRFeatureName","Matrix","Vector3","Color3","Axis","StandardMaterial","CreateCylinder","CreateTorus","Ray","PickingInfo","WebXRAbstractFeature","UtilityLayerRenderer","Viewport","Tools","WebXRControllerPointerSelection","constructor","_xrSessionManager","_options","_attachController","xrController","_controllers","uniqueId","laserPointer","selectionMesh","_generateNewMeshPair","forceGripIfAvailable","grip","pointer","meshUnderPointer","pick","tmpRay","disabledByNearInteraction","id","_IdCounter","_attachedController","enablePointerSelectionOnAllControllers","preferredHandedness","inputSource","handedness","targetRayMode","_attachTrackedPointerRayMode","_attachGazeMode","_attachScreenRayMode","_tmpVectorForPickCompare","disablePointerLighting","disableSelectionMeshLighting","displayLaserPointer","displaySelectionMesh","laserPointerPickedColor","laserPointerDefaultColor","selectionMeshDefaultColor","selectionMeshPickedColor","_identityMatrix","Identity","_screenCoordinatesRef","Zero","_viewportRef","_scene","scene","lookAndPickMode","undefined","getEngine","_badDesktopOS","_badOS","attach","xrInput","controllers","forEach","_addNewAttachObserver","onControllerAddedObservable","onControllerRemovedObservable","controller","_detachController","constantlyUpdateMeshUnderPointer","gazeCamera","webXRCamera","detach","Object","keys","controllerId","getMeshUnderPointer","getXRControllerByPointerId","i","length","_getPointerSelectionDisabledByPointerId","_setPointerSelectionDisabledByPointerId","state","_onXRFrame","_xrFrame","_controllerData$xrCon","controllerData","isVisible","controllerGlobalPosition","position","getWorldPointerRayToRef","getForwardRayToRef","maxPointerDistance","disableScenePointerVectorUpdate","camera","xrCamera","viewport","toGlobalToRef","getRenderWidth","rigCameras","getRenderHeight","ProjectToRef","getTransformationMatrix","x","y","isNaN","Infinity","pointerX","pointerY","screenCoordinates","utilityScenePick","_utilityLayerScene","pickWithRay","pointerMovePredicate","raySelectionPredicate","originalScenePick","hit","distance","aimTransform","gripTransform","originMesh","pickedPoint","_updatePointerDistance","copyFrom","scaling","Math","sqrt","z","pickNormal","_convertNormalToDirectionOfRay","getNormal","deltaFighting","axis1","Cross","Y","axis2","RotationFromAxisToRef","rotation","addInPlace","scale","pickedMesh","customUtilityLayerScene","DefaultUtilityLayer","utilityLayerScene","timeToSelect","sceneToRenderTo","useUtilityLayer","oldPick","discMesh","diameter","thickness","tessellation","isPickable","parent","timer","downTriggered","pointerEventInit","pointerId","pointerType","onFrameObserver","onXRFrameObservable","add","_augmentPointerInit","material","alpha","_pickingMoved","getDeltaTime","simulatePointerDown","disablePointerUpOnTouchOut","simulatePointerUp","scaleFactor","set","simulatePointerMove","renderingGroupId","onDisposeObservable","addOnce","finalPointerUpTriggered","dispose","pointerDownTriggered","runInXRFrame","forceGazeMode","disableLighting","gamepad","init","motionController","overrideButtonId","selectionComponent","getComponent","getMainComponent","onButtonChangedObserver","onButtonStateChangedObservable","component","changes","pressed","current","emissiveColor","disableSwitchOnClick","prevController","onMotionControllerInitObservable","selectStartListener","event","selectEndListener","eventListeners","selectend","selectstart","session","addEventListener","normal","ray","angle","acos","Dot","direction","PI","scaleInPlace","xrControllerUniqueId","remove","eventName","func","removeEventListener","onBeforeRenderObservable","e","Warn","meshParent","customLasterPointerMeshGenerator","height","diameterTop","diameterBottom","subdivisions","laserPointerMaterial","customSelectionMeshGenerator","bakeCurrentTransformIntoVertices","targetMat","specularColor","Black","backFaceCulling","newPick","_oldPick$pickedPoint","subtractToRef","abs","delta","gazeModePointerMovedFactor","_laserPointer","useRightHandedSystem","screenX","screenY","lasterPointerDefaultColor","Name","POINTER_SELECTION","Version","AddWebXRFeature","xrSessionManager","options"],"sources":["F:/workspace/202226701027/huinongbao-app/node_modules/@babylonjs/core/XR/features/WebXRControllerPointerSelection.js"],"sourcesContent":["import { WebXRFeaturesManager, WebXRFeatureName } from \"../webXRFeaturesManager.js\";\nimport { Matrix, Vector3 } from \"../../Maths/math.vector.js\";\nimport { Color3 } from \"../../Maths/math.color.js\";\nimport { Axis } from \"../../Maths/math.axis.js\";\nimport { StandardMaterial } from \"../../Materials/standardMaterial.js\";\nimport { CreateCylinder } from \"../../Meshes/Builders/cylinderBuilder.js\";\nimport { CreateTorus } from \"../../Meshes/Builders/torusBuilder.js\";\nimport { Ray } from \"../../Culling/ray.js\";\nimport { PickingInfo } from \"../../Collisions/pickingInfo.js\";\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature.js\";\nimport { UtilityLayerRenderer } from \"../../Rendering/utilityLayerRenderer.js\";\nimport { Viewport } from \"../../Maths/math.viewport.js\";\nimport { Tools } from \"../../Misc/tools.js\";\n/**\n * A module that will enable pointer selection for motion controllers of XR Input Sources\n */\nexport class WebXRControllerPointerSelection extends WebXRAbstractFeature {\n /**\n * constructs a new background remover module\n * @param _xrSessionManager the session manager for this module\n * @param _options read-only options to be used in this module\n */\n constructor(_xrSessionManager, _options) {\n super(_xrSessionManager);\n this._options = _options;\n this._attachController = (xrController) => {\n if (this._controllers[xrController.uniqueId]) {\n // already attached\n return;\n }\n const { laserPointer, selectionMesh } = this._generateNewMeshPair(this._options.forceGripIfAvailable && xrController.grip ? xrController.grip : xrController.pointer);\n // get two new meshes\n this._controllers[xrController.uniqueId] = {\n xrController,\n laserPointer,\n selectionMesh,\n meshUnderPointer: null,\n pick: null,\n tmpRay: new Ray(new Vector3(), new Vector3()),\n disabledByNearInteraction: false,\n id: WebXRControllerPointerSelection._IdCounter++,\n };\n if (this._attachedController) {\n if (!this._options.enablePointerSelectionOnAllControllers &&\n this._options.preferredHandedness &&\n xrController.inputSource.handedness === this._options.preferredHandedness) {\n this._attachedController = xrController.uniqueId;\n }\n }\n else {\n if (!this._options.enablePointerSelectionOnAllControllers) {\n this._attachedController = xrController.uniqueId;\n }\n }\n switch (xrController.inputSource.targetRayMode) {\n case \"tracked-pointer\":\n return this._attachTrackedPointerRayMode(xrController);\n case \"gaze\":\n return this._attachGazeMode(xrController);\n case \"screen\":\n case \"transient-pointer\":\n return this._attachScreenRayMode(xrController);\n }\n };\n this._controllers = {};\n this._tmpVectorForPickCompare = new Vector3();\n /**\n * Disable lighting on the laser pointer (so it will always be visible)\n */\n this.disablePointerLighting = true;\n /**\n * Disable lighting on the selection mesh (so it will always be visible)\n */\n this.disableSelectionMeshLighting = true;\n /**\n * Should the laser pointer be displayed\n */\n this.displayLaserPointer = true;\n /**\n * Should the selection mesh be displayed (The ring at the end of the laser pointer)\n */\n this.displaySelectionMesh = true;\n /**\n * This color will be set to the laser pointer when selection is triggered\n */\n this.laserPointerPickedColor = new Color3(0.9, 0.9, 0.9);\n /**\n * Default color of the laser pointer\n */\n this.laserPointerDefaultColor = new Color3(0.7, 0.7, 0.7);\n /**\n * default color of the selection ring\n */\n this.selectionMeshDefaultColor = new Color3(0.8, 0.8, 0.8);\n /**\n * This color will be applied to the selection ring when selection is triggered\n */\n this.selectionMeshPickedColor = new Color3(0.3, 0.3, 1.0);\n this._identityMatrix = Matrix.Identity();\n this._screenCoordinatesRef = Vector3.Zero();\n this._viewportRef = new Viewport(0, 0, 0, 0);\n this._scene = this._xrSessionManager.scene;\n // force look and pick mode if using WebXR on safari, assuming it is vision OS\n // Only if not explicitly set. If set to false, it will not be forced\n if (this._options.lookAndPickMode === undefined && (this._scene.getEngine()._badDesktopOS || this._scene.getEngine()._badOS)) {\n this._options.lookAndPickMode = true;\n }\n // look and pick mode extra state changes\n if (this._options.lookAndPickMode) {\n this._options.enablePointerSelectionOnAllControllers = true;\n this.displayLaserPointer = false;\n }\n }\n /**\n * attach this feature\n * Will usually be called by the features manager\n *\n * @returns true if successful.\n */\n attach() {\n if (!super.attach()) {\n return false;\n }\n this._options.xrInput.controllers.forEach(this._attachController);\n this._addNewAttachObserver(this._options.xrInput.onControllerAddedObservable, this._attachController, true);\n this._addNewAttachObserver(this._options.xrInput.onControllerRemovedObservable, (controller) => {\n // REMOVE the controller\n this._detachController(controller.uniqueId);\n }, true);\n this._scene.constantlyUpdateMeshUnderPointer = true;\n if (this._options.gazeCamera) {\n const webXRCamera = this._options.gazeCamera;\n const { laserPointer, selectionMesh } = this._generateNewMeshPair(webXRCamera);\n this._controllers[\"camera\"] = {\n webXRCamera,\n laserPointer,\n selectionMesh,\n meshUnderPointer: null,\n pick: null,\n tmpRay: new Ray(new Vector3(), new Vector3()),\n disabledByNearInteraction: false,\n id: WebXRControllerPointerSelection._IdCounter++,\n };\n this._attachGazeMode();\n }\n return true;\n }\n /**\n * detach this feature.\n * Will usually be called by the features manager\n *\n * @returns true if successful.\n */\n detach() {\n if (!super.detach()) {\n return false;\n }\n Object.keys(this._controllers).forEach((controllerId) => {\n this._detachController(controllerId);\n });\n return true;\n }\n /**\n * Will get the mesh under a specific pointer.\n * `scene.meshUnderPointer` will only return one mesh - either left or right.\n * @param controllerId the controllerId to check\n * @returns The mesh under pointer or null if no mesh is under the pointer\n */\n getMeshUnderPointer(controllerId) {\n if (this._controllers[controllerId]) {\n return this._controllers[controllerId].meshUnderPointer;\n }\n else {\n return null;\n }\n }\n /**\n * Get the xr controller that correlates to the pointer id in the pointer event\n *\n * @param id the pointer id to search for\n * @returns the controller that correlates to this id or null if not found\n */\n getXRControllerByPointerId(id) {\n const keys = Object.keys(this._controllers);\n for (let i = 0; i < keys.length; ++i) {\n if (this._controllers[keys[i]].id === id) {\n return this._controllers[keys[i]].xrController || null;\n }\n }\n return null;\n }\n /**\n * @internal\n */\n _getPointerSelectionDisabledByPointerId(id) {\n const keys = Object.keys(this._controllers);\n for (let i = 0; i < keys.length; ++i) {\n if (this._controllers[keys[i]].id === id) {\n return this._controllers[keys[i]].disabledByNearInteraction;\n }\n }\n return true;\n }\n /**\n * @internal\n */\n _setPointerSelectionDisabledByPointerId(id, state) {\n const keys = Object.keys(this._controllers);\n for (let i = 0; i < keys.length; ++i) {\n if (this._controllers[keys[i]].id === id) {\n this._controllers[keys[i]].disabledByNearInteraction = state;\n return;\n }\n }\n }\n _onXRFrame(_xrFrame) {\n Object.keys(this._controllers).forEach((id) => {\n // look and pick mode\n // only do this for the selected pointer\n const controllerData = this._controllers[id];\n if (this._options.lookAndPickMode && controllerData.xrController?.inputSource.targetRayMode !== \"transient-pointer\") {\n return;\n }\n if ((!this._options.enablePointerSelectionOnAllControllers && id !== this._attachedController) || controllerData.disabledByNearInteraction) {\n controllerData.selectionMesh.isVisible = false;\n controllerData.laserPointer.isVisible = false;\n controllerData.pick = null;\n return;\n }\n controllerData.laserPointer.isVisible = this.displayLaserPointer;\n let controllerGlobalPosition;\n // Every frame check collisions/input\n if (controllerData.xrController) {\n controllerGlobalPosition =\n this._options.forceGripIfAvailable && controllerData.xrController.grip\n ? controllerData.xrController.grip.position\n : controllerData.xrController.pointer.position;\n controllerData.xrController.getWorldPointerRayToRef(controllerData.tmpRay, this._options.forceGripIfAvailable);\n }\n else if (controllerData.webXRCamera) {\n controllerGlobalPosition = controllerData.webXRCamera.position;\n controllerData.webXRCamera.getForwardRayToRef(controllerData.tmpRay);\n }\n else {\n return;\n }\n if (this._options.maxPointerDistance) {\n controllerData.tmpRay.length = this._options.maxPointerDistance;\n }\n // update pointerX and pointerY of the scene. Only if the flag is set to true!\n if (!this._options.disableScenePointerVectorUpdate && controllerGlobalPosition) {\n const scene = this._xrSessionManager.scene;\n const camera = this._options.xrInput.xrCamera;\n if (camera) {\n camera.viewport.toGlobalToRef(scene.getEngine().getRenderWidth() / camera.rigCameras.length, scene.getEngine().getRenderHeight(), this._viewportRef);\n Vector3.ProjectToRef(controllerGlobalPosition, this._identityMatrix, camera.getTransformationMatrix(), this._viewportRef, this._screenCoordinatesRef);\n // stay safe\n if (typeof this._screenCoordinatesRef.x === \"number\" &&\n typeof this._screenCoordinatesRef.y === \"number\" &&\n !isNaN(this._screenCoordinatesRef.x) &&\n !isNaN(this._screenCoordinatesRef.y) &&\n this._screenCoordinatesRef.x !== Infinity &&\n this._screenCoordinatesRef.y !== Infinity) {\n scene.pointerX = this._screenCoordinatesRef.x;\n scene.pointerY = this._screenCoordinatesRef.y;\n controllerData.screenCoordinates = {\n x: this._screenCoordinatesRef.x,\n y: this._screenCoordinatesRef.y,\n };\n }\n }\n }\n let utilityScenePick = null;\n if (this._utilityLayerScene) {\n utilityScenePick = this._utilityLayerScene.pickWithRay(controllerData.tmpRay, this._utilityLayerScene.pointerMovePredicate || this.raySelectionPredicate);\n }\n const originalScenePick = this._scene.pickWithRay(controllerData.tmpRay, this._scene.pointerMovePredicate || this.raySelectionPredicate);\n if (!utilityScenePick || !utilityScenePick.hit) {\n // No hit in utility scene\n controllerData.pick = originalScenePick;\n }\n else if (!originalScenePick || !originalScenePick.hit) {\n // No hit in original scene\n controllerData.pick = utilityScenePick;\n }\n else if (utilityScenePick.distance < originalScenePick.distance) {\n // Hit is closer in utility scene\n controllerData.pick = utilityScenePick;\n }\n else {\n // Hit is closer in original scene\n controllerData.pick = originalScenePick;\n }\n if (controllerData.pick && controllerData.xrController) {\n controllerData.pick.aimTransform = controllerData.xrController.pointer;\n controllerData.pick.gripTransform = controllerData.xrController.grip || null;\n controllerData.pick.originMesh = controllerData.xrController.pointer;\n }\n const pick = controllerData.pick;\n if (pick && pick.pickedPoint && pick.hit) {\n // Update laser state\n this._updatePointerDistance(controllerData.laserPointer, pick.distance);\n // Update cursor state\n controllerData.selectionMesh.position.copyFrom(pick.pickedPoint);\n controllerData.selectionMesh.scaling.x = Math.sqrt(pick.distance);\n controllerData.selectionMesh.scaling.y = Math.sqrt(pick.distance);\n controllerData.selectionMesh.scaling.z = Math.sqrt(pick.distance);\n // To avoid z-fighting\n const pickNormal = this._convertNormalToDirectionOfRay(pick.getNormal(true), controllerData.tmpRay);\n const deltaFighting = 0.001;\n controllerData.selectionMesh.position.copyFrom(pick.pickedPoint);\n if (pickNormal) {\n const axis1 = Vector3.Cross(Axis.Y, pickNormal);\n const axis2 = Vector3.Cross(pickNormal, axis1);\n Vector3.RotationFromAxisToRef(axis2, pickNormal, axis1, controllerData.selectionMesh.rotation);\n controllerData.selectionMesh.position.addInPlace(pickNormal.scale(deltaFighting));\n }\n controllerData.selectionMesh.isVisible = this.displaySelectionMesh;\n controllerData.meshUnderPointer = pick.pickedMesh;\n }\n else {\n controllerData.selectionMesh.isVisible = false;\n this._updatePointerDistance(controllerData.laserPointer, 1);\n controllerData.meshUnderPointer = null;\n }\n });\n }\n get _utilityLayerScene() {\n return this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene;\n }\n _attachGazeMode(xrController) {\n const controllerData = this._controllers[(xrController && xrController.uniqueId) || \"camera\"];\n // attached when touched, detaches when raised\n const timeToSelect = this._options.timeToSelect || 3000;\n const sceneToRenderTo = this._options.useUtilityLayer ? this._utilityLayerScene : this._scene;\n let oldPick = new PickingInfo();\n const discMesh = CreateTorus(\"selection\", {\n diameter: 0.0035 * 15,\n thickness: 0.0025 * 6,\n tessellation: 20,\n }, sceneToRenderTo);\n discMesh.isVisible = false;\n discMesh.isPickable = false;\n discMesh.parent = controllerData.selectionMesh;\n let timer = 0;\n let downTriggered = false;\n const pointerEventInit = {\n pointerId: controllerData.id,\n pointerType: \"xr\",\n };\n controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {\n if (!controllerData.pick) {\n return;\n }\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n controllerData.laserPointer.material.alpha = 0;\n discMesh.isVisible = false;\n if (controllerData.pick.hit) {\n if (!this._pickingMoved(oldPick, controllerData.pick)) {\n if (timer > timeToSelect / 10) {\n discMesh.isVisible = true;\n }\n timer += this._scene.getEngine().getDeltaTime();\n if (timer >= timeToSelect) {\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\n // this pointerdown event is not setting the controllerData.pointerDownTriggered to avoid a pointerUp event when this feature is detached\n downTriggered = true;\n // pointer up right after down, if disable on touch out\n if (this._options.disablePointerUpOnTouchOut) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n }\n discMesh.isVisible = false;\n }\n else {\n const scaleFactor = 1 - timer / timeToSelect;\n discMesh.scaling.set(scaleFactor, scaleFactor, scaleFactor);\n }\n }\n else {\n if (downTriggered) {\n if (!this._options.disablePointerUpOnTouchOut) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n }\n }\n downTriggered = false;\n timer = 0;\n }\n }\n else {\n downTriggered = false;\n timer = 0;\n }\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\n oldPick = controllerData.pick;\n });\n if (this._options.renderingGroupId !== undefined) {\n discMesh.renderingGroupId = this._options.renderingGroupId;\n }\n if (xrController) {\n xrController.onDisposeObservable.addOnce(() => {\n if (controllerData.pick && !this._options.disablePointerUpOnTouchOut && downTriggered) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n controllerData.finalPointerUpTriggered = true;\n }\n discMesh.dispose();\n });\n }\n }\n _attachScreenRayMode(xrController) {\n const controllerData = this._controllers[xrController.uniqueId];\n let downTriggered = false;\n const pointerEventInit = {\n pointerId: controllerData.id,\n pointerType: \"xr\",\n };\n controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n if (!controllerData.pick || (this._options.disablePointerUpOnTouchOut && downTriggered)) {\n return;\n }\n if (!downTriggered) {\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\n controllerData.pointerDownTriggered = true;\n downTriggered = true;\n if (this._options.disablePointerUpOnTouchOut) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n }\n }\n else {\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\n }\n });\n xrController.onDisposeObservable.addOnce(() => {\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n this._xrSessionManager.runInXRFrame(() => {\n if (controllerData.pick && !controllerData.finalPointerUpTriggered && downTriggered && !this._options.disablePointerUpOnTouchOut) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n controllerData.finalPointerUpTriggered = true;\n }\n });\n });\n }\n _attachTrackedPointerRayMode(xrController) {\n const controllerData = this._controllers[xrController.uniqueId];\n if (this._options.forceGazeMode) {\n return this._attachGazeMode(xrController);\n }\n const pointerEventInit = {\n pointerId: controllerData.id,\n pointerType: \"xr\",\n };\n controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {\n controllerData.laserPointer.material.disableLighting = this.disablePointerLighting;\n controllerData.selectionMesh.material.disableLighting = this.disableSelectionMeshLighting;\n if (controllerData.pick) {\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\n }\n });\n if (xrController.inputSource.gamepad) {\n const init = (motionController) => {\n if (this._options.overrideButtonId) {\n controllerData.selectionComponent = motionController.getComponent(this._options.overrideButtonId);\n }\n if (!controllerData.selectionComponent) {\n controllerData.selectionComponent = motionController.getMainComponent();\n }\n controllerData.onButtonChangedObserver = controllerData.selectionComponent.onButtonStateChangedObservable.add((component) => {\n if (component.changes.pressed) {\n const pressed = component.changes.pressed.current;\n if (controllerData.pick) {\n if (this._options.enablePointerSelectionOnAllControllers || xrController.uniqueId === this._attachedController) {\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n if (pressed) {\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\n controllerData.pointerDownTriggered = true;\n controllerData.selectionMesh.material.emissiveColor = this.selectionMeshPickedColor;\n controllerData.laserPointer.material.emissiveColor = this.laserPointerPickedColor;\n }\n else {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n controllerData.selectionMesh.material.emissiveColor = this.selectionMeshDefaultColor;\n controllerData.laserPointer.material.emissiveColor = this.laserPointerDefaultColor;\n }\n }\n }\n else {\n if (pressed && !this._options.enablePointerSelectionOnAllControllers && !this._options.disableSwitchOnClick) {\n // force a pointer up if switching controllers\n // get the controller that was attached before\n const prevController = this._controllers[this._attachedController];\n if (prevController && prevController.pointerDownTriggered && !prevController.finalPointerUpTriggered) {\n this._augmentPointerInit(pointerEventInit, prevController.id, prevController.screenCoordinates);\n this._scene.simulatePointerUp(new PickingInfo(), {\n pointerId: prevController.id,\n pointerType: \"xr\",\n });\n prevController.finalPointerUpTriggered = true;\n }\n this._attachedController = xrController.uniqueId;\n }\n }\n }\n });\n };\n if (xrController.motionController) {\n init(xrController.motionController);\n }\n else {\n xrController.onMotionControllerInitObservable.add(init);\n }\n }\n else {\n // use the select and squeeze events\n const selectStartListener = (event) => {\n this._xrSessionManager.onXRFrameObservable.addOnce(() => {\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick) {\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\n controllerData.pointerDownTriggered = true;\n controllerData.selectionMesh.material.emissiveColor = this.selectionMeshPickedColor;\n controllerData.laserPointer.material.emissiveColor = this.laserPointerPickedColor;\n }\n });\n };\n const selectEndListener = (event) => {\n this._xrSessionManager.onXRFrameObservable.addOnce(() => {\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n controllerData.selectionMesh.material.emissiveColor = this.selectionMeshDefaultColor;\n controllerData.laserPointer.material.emissiveColor = this.laserPointerDefaultColor;\n }\n });\n };\n controllerData.eventListeners = {\n selectend: selectEndListener,\n selectstart: selectStartListener,\n };\n this._xrSessionManager.session.addEventListener(\"selectstart\", selectStartListener);\n this._xrSessionManager.session.addEventListener(\"selectend\", selectEndListener);\n }\n }\n _convertNormalToDirectionOfRay(normal, ray) {\n if (normal) {\n const angle = Math.acos(Vector3.Dot(normal, ray.direction));\n if (angle < Math.PI / 2) {\n normal.scaleInPlace(-1);\n }\n }\n return normal;\n }\n _detachController(xrControllerUniqueId) {\n const controllerData = this._controllers[xrControllerUniqueId];\n if (!controllerData) {\n return;\n }\n if (controllerData.selectionComponent) {\n if (controllerData.onButtonChangedObserver) {\n controllerData.selectionComponent.onButtonStateChangedObservable.remove(controllerData.onButtonChangedObserver);\n }\n }\n if (controllerData.onFrameObserver) {\n this._xrSessionManager.onXRFrameObservable.remove(controllerData.onFrameObserver);\n }\n if (controllerData.eventListeners) {\n Object.keys(controllerData.eventListeners).forEach((eventName) => {\n const func = controllerData.eventListeners && controllerData.eventListeners[eventName];\n if (func) {\n // For future reference - this is an issue in the WebXR typings.\n this._xrSessionManager.session.removeEventListener(eventName, func);\n }\n });\n }\n if (!controllerData.finalPointerUpTriggered && controllerData.pointerDownTriggered) {\n // Stay safe and fire a pointerup, in case it wasn't already triggered\n const pointerEventInit = {\n pointerId: controllerData.id,\n pointerType: \"xr\",\n };\n this._xrSessionManager.runInXRFrame(() => {\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\n this._scene.simulatePointerUp(controllerData.pick || new PickingInfo(), pointerEventInit);\n controllerData.finalPointerUpTriggered = true;\n });\n }\n this._xrSessionManager.scene.onBeforeRenderObservable.addOnce(() => {\n try {\n controllerData.selectionMesh.dispose();\n controllerData.laserPointer.dispose();\n // remove from the map\n delete this._controllers[xrControllerUniqueId];\n if (this._attachedController === xrControllerUniqueId) {\n // check for other controllers\n const keys = Object.keys(this._controllers);\n if (keys.length) {\n this._attachedController = keys[0];\n }\n else {\n this._attachedController = \"\";\n }\n }\n }\n catch (e) {\n Tools.Warn(\"controller already detached.\");\n }\n });\n }\n _generateNewMeshPair(meshParent) {\n const sceneToRenderTo = this._options.useUtilityLayer ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene : this._scene;\n const laserPointer = this._options.customLasterPointerMeshGenerator\n ? this._options.customLasterPointerMeshGenerator()\n : CreateCylinder(\"laserPointer\", {\n height: 1,\n diameterTop: 0.0002,\n diameterBottom: 0.004,\n tessellation: 20,\n subdivisions: 1,\n }, sceneToRenderTo);\n laserPointer.parent = meshParent;\n const laserPointerMaterial = new StandardMaterial(\"laserPointerMat\", sceneToRenderTo);\n laserPointerMaterial.emissiveColor = this.laserPointerDefaultColor;\n laserPointerMaterial.alpha = 0.7;\n laserPointer.material = laserPointerMaterial;\n laserPointer.rotation.x = Math.PI / 2;\n this._updatePointerDistance(laserPointer, 1);\n laserPointer.isPickable = false;\n laserPointer.isVisible = false;\n // Create a gaze tracker for the XR controller\n const selectionMesh = this._options.customSelectionMeshGenerator\n ? this._options.customSelectionMeshGenerator()\n : CreateTorus(\"gazeTracker\", {\n diameter: 0.0035 * 3,\n thickness: 0.0025 * 3,\n tessellation: 20,\n }, sceneToRenderTo);\n selectionMesh.bakeCurrentTransformIntoVertices();\n selectionMesh.isPickable = false;\n selectionMesh.isVisible = false;\n const targetMat = new StandardMaterial(\"targetMat\", sceneToRenderTo);\n targetMat.specularColor = Color3.Black();\n targetMat.emissiveColor = this.selectionMeshDefaultColor;\n targetMat.backFaceCulling = false;\n selectionMesh.material = targetMat;\n if (this._options.renderingGroupId !== undefined) {\n laserPointer.renderingGroupId = this._options.renderingGroupId;\n selectionMesh.renderingGroupId = this._options.renderingGroupId;\n }\n return {\n laserPointer,\n selectionMesh,\n };\n }\n _pickingMoved(oldPick, newPick) {\n if (!oldPick.hit || !newPick.hit) {\n return true;\n }\n if (!oldPick.pickedMesh || !oldPick.pickedPoint || !newPick.pickedMesh || !newPick.pickedPoint) {\n return true;\n }\n if (oldPick.pickedMesh !== newPick.pickedMesh) {\n return true;\n }\n oldPick.pickedPoint?.subtractToRef(newPick.pickedPoint, this._tmpVectorForPickCompare);\n this._tmpVectorForPickCompare.set(Math.abs(this._tmpVectorForPickCompare.x), Math.abs(this._tmpVectorForPickCompare.y), Math.abs(this._tmpVectorForPickCompare.z));\n const delta = (this._options.gazeModePointerMovedFactor || 1) * 0.01 * newPick.distance;\n const length = this._tmpVectorForPickCompare.length();\n if (length > delta) {\n return true;\n }\n return false;\n }\n _updatePointerDistance(_laserPointer, distance = 100) {\n _laserPointer.scaling.y = distance;\n // a bit of distance from the controller\n if (this._scene.useRightHandedSystem) {\n distance *= -1;\n }\n _laserPointer.position.z = distance / 2 + 0.05;\n }\n _augmentPointerInit(pointerEventInit, id, screenCoordinates) {\n pointerEventInit.pointerId = id;\n pointerEventInit.pointerType = \"xr\";\n if (screenCoordinates) {\n pointerEventInit.screenX = screenCoordinates.x;\n pointerEventInit.screenY = screenCoordinates.y;\n }\n }\n /** @internal */\n get lasterPointerDefaultColor() {\n // here due to a typo\n return this.laserPointerDefaultColor;\n }\n}\nWebXRControllerPointerSelection._IdCounter = 200;\n/**\n * The module's name\n */\nWebXRControllerPointerSelection.Name = WebXRFeatureName.POINTER_SELECTION;\n/**\n * The (Babylon) version of this module.\n * This is an integer representing the implementation version.\n * This number does not correspond to the WebXR specs version\n */\nWebXRControllerPointerSelection.Version = 1;\n//register the plugin\nWebXRFeaturesManager.AddWebXRFeature(WebXRControllerPointerSelection.Name, (xrSessionManager, options) => {\n return () => new WebXRControllerPointerSelection(xrSessionManager, options);\n}, WebXRControllerPointerSelection.Version, true);\n"],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]}