@babylonjs/core 5.0.0-alpha.65 → 5.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/Animations/animation.js +3 -0
  2. package/Animations/animation.js.map +1 -1
  3. package/Bones/bone.js +3 -0
  4. package/Bones/bone.js.map +1 -1
  5. package/Cameras/Inputs/freeCameraTouchInput.d.ts +2 -2
  6. package/Cameras/Inputs/freeCameraTouchInput.js +6 -4
  7. package/Cameras/Inputs/freeCameraTouchInput.js.map +1 -1
  8. package/Collisions/collider.d.ts +1 -1
  9. package/Collisions/collider.js +13 -3
  10. package/Collisions/collider.js.map +1 -1
  11. package/Engines/Extensions/engine.renderTarget.js +1 -0
  12. package/Engines/Extensions/engine.renderTarget.js.map +1 -1
  13. package/Engines/WebGPU/Extensions/engine.cubeTexture.js +1 -1
  14. package/Engines/WebGPU/Extensions/engine.cubeTexture.js.map +1 -1
  15. package/Engines/WebGPU/Extensions/engine.dynamicTexture.js +1 -1
  16. package/Engines/WebGPU/Extensions/engine.dynamicTexture.js.map +1 -1
  17. package/Engines/WebGPU/Extensions/engine.rawTexture.js +5 -5
  18. package/Engines/WebGPU/Extensions/engine.rawTexture.js.map +1 -1
  19. package/Engines/WebGPU/Extensions/engine.renderTarget.js +2 -4
  20. package/Engines/WebGPU/Extensions/engine.renderTarget.js.map +1 -1
  21. package/Engines/WebGPU/Extensions/engine.videoTexture.js +1 -1
  22. package/Engines/WebGPU/Extensions/engine.videoTexture.js.map +1 -1
  23. package/Engines/WebGPU/webgpuCacheRenderPipeline.js +4 -0
  24. package/Engines/WebGPU/webgpuCacheRenderPipeline.js.map +1 -1
  25. package/Engines/WebGPU/webgpuClearQuad.d.ts +1 -0
  26. package/Engines/WebGPU/webgpuClearQuad.js +10 -7
  27. package/Engines/WebGPU/webgpuClearQuad.js.map +1 -1
  28. package/Engines/WebGPU/webgpuHardwareTexture.d.ts +3 -1
  29. package/Engines/WebGPU/webgpuHardwareTexture.js.map +1 -1
  30. package/Engines/WebGPU/webgpuTextureHelper.d.ts +4 -3
  31. package/Engines/WebGPU/webgpuTextureHelper.js +80 -45
  32. package/Engines/WebGPU/webgpuTextureHelper.js.map +1 -1
  33. package/Engines/engine.d.ts +1 -0
  34. package/Engines/renderTargetWrapper.js +1 -1
  35. package/Engines/renderTargetWrapper.js.map +1 -1
  36. package/Engines/thinEngine.js +2 -2
  37. package/Engines/thinEngine.js.map +1 -1
  38. package/Engines/webgpuEngine.js +5 -5
  39. package/Engines/webgpuEngine.js.map +1 -1
  40. package/Layers/effectLayer.js +23 -0
  41. package/Layers/effectLayer.js.map +1 -1
  42. package/Layers/glowLayer.js +2 -0
  43. package/Layers/glowLayer.js.map +1 -1
  44. package/Lights/light.d.ts +1 -0
  45. package/Lights/light.js +2 -1
  46. package/Lights/light.js.map +1 -1
  47. package/Materials/Textures/baseTexture.d.ts +6 -2
  48. package/Materials/Textures/baseTexture.js +60 -16
  49. package/Materials/Textures/baseTexture.js.map +1 -1
  50. package/Materials/Textures/renderTargetTexture.d.ts +10 -5
  51. package/Materials/Textures/renderTargetTexture.js +18 -6
  52. package/Materials/Textures/renderTargetTexture.js.map +1 -1
  53. package/Materials/Textures/texture.d.ts +3 -0
  54. package/Materials/Textures/texture.js +3 -0
  55. package/Materials/Textures/texture.js.map +1 -1
  56. package/Materials/materialDefines.d.ts +1 -0
  57. package/Materials/materialDefines.js +24 -15
  58. package/Materials/materialDefines.js.map +1 -1
  59. package/Materials/materialPluginBase.d.ts +6 -1
  60. package/Materials/materialPluginBase.js +7 -1
  61. package/Materials/materialPluginBase.js.map +1 -1
  62. package/Meshes/Builders/goldbergBuilder.d.ts +45 -42
  63. package/Meshes/Builders/goldbergBuilder.js +14 -225
  64. package/Meshes/Builders/goldbergBuilder.js.map +1 -1
  65. package/Meshes/Builders/index.d.ts +1 -0
  66. package/Meshes/Builders/index.js +1 -0
  67. package/Meshes/Builders/index.js.map +1 -1
  68. package/Meshes/Builders/shapeBuilder.d.ts +10 -2
  69. package/Meshes/Builders/shapeBuilder.js +11 -5
  70. package/Meshes/Builders/shapeBuilder.js.map +1 -1
  71. package/Meshes/abstractMesh.d.ts +4 -1
  72. package/Meshes/abstractMesh.js +8 -3
  73. package/Meshes/abstractMesh.js.map +1 -1
  74. package/Meshes/geodesicMesh.d.ts +1 -1
  75. package/Meshes/geodesicMesh.js +6 -6
  76. package/Meshes/geodesicMesh.js.map +1 -1
  77. package/Meshes/goldbergMesh.d.ts +107 -0
  78. package/Meshes/goldbergMesh.js +244 -0
  79. package/Meshes/goldbergMesh.js.map +1 -0
  80. package/Meshes/index.d.ts +1 -0
  81. package/Meshes/index.js +1 -0
  82. package/Meshes/index.js.map +1 -1
  83. package/Meshes/mesh.d.ts +5 -0
  84. package/Meshes/mesh.js +11 -0
  85. package/Meshes/mesh.js.map +1 -1
  86. package/Meshes/mesh.lts.d.ts +10 -6
  87. package/Meshes/mesh.lts.js +1 -1
  88. package/Meshes/mesh.lts.js.map +1 -1
  89. package/Meshes/subMesh.d.ts +2 -1
  90. package/Meshes/subMesh.js +11 -4
  91. package/Meshes/subMesh.js.map +1 -1
  92. package/Misc/timer.js +1 -0
  93. package/Misc/timer.js.map +1 -1
  94. package/Physics/Plugins/ammoJSPlugin.d.ts +4 -0
  95. package/Physics/Plugins/ammoJSPlugin.js +11 -6
  96. package/Physics/Plugins/ammoJSPlugin.js.map +1 -1
  97. package/PostProcesses/volumetricLightScatteringPostProcess.js +22 -0
  98. package/PostProcesses/volumetricLightScatteringPostProcess.js.map +1 -1
  99. package/Rendering/depthRenderer.js +18 -0
  100. package/Rendering/depthRenderer.js.map +1 -1
  101. package/Rendering/geometryBufferRenderer.js +23 -1
  102. package/Rendering/geometryBufferRenderer.js.map +1 -1
  103. package/XR/features/WebXRControllerPointerSelection.js +6 -4
  104. package/XR/features/WebXRControllerPointerSelection.js.map +1 -1
  105. package/XR/features/WebXRNearInteraction.js +8 -6
  106. package/XR/features/WebXRNearInteraction.js.map +1 -1
  107. package/XR/webXRExperienceHelper.js +7 -0
  108. package/XR/webXRExperienceHelper.js.map +1 -1
  109. package/XR/webXRRenderTargetTextureProvider.js +1 -3
  110. package/XR/webXRRenderTargetTextureProvider.js.map +1 -1
  111. package/XR/webXRSessionManager.d.ts +14 -1
  112. package/XR/webXRSessionManager.js +31 -8
  113. package/XR/webXRSessionManager.js.map +1 -1
  114. package/package.json +4 -1
  115. package/scene.d.ts +2 -1
  116. package/scene.js +3 -2
  117. package/scene.js.map +1 -1
@@ -488,12 +488,14 @@ var WebXRNearInteraction = /** @class */ (function (_super) {
488
488
  }
489
489
  (_a = controllerData.pickIndexMeshTip) === null || _a === void 0 ? void 0 : _a.dispose();
490
490
  controllerData.pickedPointVisualCue.dispose();
491
- // Fire a pointerup
492
- var pointerEventInit = {
493
- pointerId: controllerData.id,
494
- pointerType: "xr",
495
- };
496
- this._scene.simulatePointerUp(new PickingInfo(), pointerEventInit);
491
+ this._xrSessionManager.runInXRFrame(function () {
492
+ // Fire a pointerup
493
+ var pointerEventInit = {
494
+ pointerId: controllerData.id,
495
+ pointerType: "xr",
496
+ };
497
+ _this._scene.simulatePointerUp(new PickingInfo(), pointerEventInit);
498
+ });
497
499
  // remove from the map
498
500
  delete this._controllers[xrControllerUniqueId];
499
501
  if (this._attachedController === xrControllerUniqueId) {
@@ -1 +1 @@
1
- {"version":3,"file":"WebXRNearInteraction.js","sourceRoot":"","sources":["../../../../sourceES6/core/XR/features/WebXRNearInteraction.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebXRFeaturesManager, WebXRFeatureName } from \"../webXRFeaturesManager\";\r\nimport { WebXRControllerPointerSelection } from \"./WebXRControllerPointerSelection\";\r\nimport { WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { CreateSphere } from \"../../Meshes/Builders/sphereBuilder\";\r\nimport { Observer } from \"../../Misc/observable\";\r\nimport { WebXRInput } from \"../webXRInput\";\r\nimport { WebXRInputSource } from \"../webXRInputSource\";\r\nimport { Scene } from \"../../scene\";\r\nimport { WebXRControllerComponent } from \"../motionController/webXRControllerComponent\";\r\nimport { IndicesArray, Nullable } from \"../../types\";\r\nimport { Vector3, Quaternion, TmpVectors } from \"../../Maths/math.vector\";\r\nimport { Ray } from \"../../Culling/ray\";\r\nimport { PickingInfo } from \"../../Collisions/pickingInfo\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { UtilityLayerRenderer } from \"../../Rendering/utilityLayerRenderer\";\r\nimport { WebXRAbstractMotionController } from \"../motionController/webXRAbstractMotionController\";\r\nimport { BoundingSphere } from \"../../Culling/boundingSphere\";\r\nimport { TransformNode } from \"../../Meshes/transformNode\";\r\nimport { StandardMaterial } from \"../../Materials/standardMaterial\";\r\nimport { Color3 } from \"../../Maths/math.color\";\r\n// side effects\r\nimport \"../../Meshes/subMesh.project\";\r\n\r\ntype ControllerData = {\r\n xrController?: WebXRInputSource;\r\n squeezeComponent?: WebXRControllerComponent;\r\n selectionComponent?: WebXRControllerComponent;\r\n onButtonChangedObserver?: Nullable<Observer<WebXRControllerComponent>>;\r\n onSqueezeButtonChangedObserver?: Nullable<Observer<WebXRControllerComponent>>;\r\n onFrameObserver?: Nullable<Observer<XRFrame>>;\r\n meshUnderPointer: Nullable<AbstractMesh>;\r\n nearInteractionMesh: Nullable<AbstractMesh>;\r\n pick: Nullable<PickingInfo>;\r\n id: number;\r\n pickIndexMeshTip: Nullable<AbstractMesh>;\r\n grabRay: Ray;\r\n nearInteraction: boolean;\r\n hoverInteraction: boolean;\r\n grabInteraction: boolean;\r\n // event support\r\n eventListeners?: { [event in XREventType]?: (event: XRInputSourceEvent) => void };\r\n pickedPointVisualCue: AbstractMesh;\r\n};\r\n\r\n/**\r\n * Options interface for the near interaction module\r\n */\r\nexport interface IWebXRNearInteractionOptions {\r\n /**\r\n * If provided, this scene will be used to render meshes.\r\n */\r\n customUtilityLayerScene?: Scene;\r\n /**\r\n * Should meshes created here be added to a utility layer or the main scene\r\n */\r\n useUtilityLayer?: boolean;\r\n /**\r\n * The xr input to use with this near interaction\r\n */\r\n xrInput: WebXRInput;\r\n /**\r\n * Enable near interaction on all controllers instead of switching between them\r\n */\r\n enableNearInteractionOnAllControllers?: boolean;\r\n /**\r\n * The preferred hand to give the near interaction to. This will be prioritized when the controller initialize.\r\n * If switch is enabled, it will still allow the user to switch between the different controllers\r\n */\r\n preferredHandedness?: XRHandedness;\r\n /**\r\n * Disable switching the near interaction from one controller to the other.\r\n * If the preferred hand is set it will be fixed on this hand, and if not it will be fixed on the first controller added to the scene\r\n */\r\n disableSwitchOnClick?: boolean;\r\n\r\n /**\r\n * Far interaction feature to toggle when near interaction takes precedence\r\n */\r\n farInteractionFeature?: WebXRControllerPointerSelection;\r\n}\r\n\r\n/**\r\n * A module that will enable near interaction near interaction for hands and motion controllers of XR Input Sources\r\n */\r\nexport class WebXRNearInteraction extends WebXRAbstractFeature {\r\n private static _idCounter = 200;\r\n\r\n private _attachController = (xrController: WebXRInputSource) => {\r\n if (this._controllers[xrController.uniqueId]) {\r\n // already attached\r\n return;\r\n }\r\n // get two new meshes\r\n const pickIndexMeshTip = this._generateNewHandTipMesh();\r\n const selectionMesh = this._generateVisualCue();\r\n\r\n this._controllers[xrController.uniqueId] = {\r\n xrController,\r\n meshUnderPointer: null,\r\n nearInteractionMesh: null,\r\n pick: null,\r\n pickIndexMeshTip,\r\n grabRay: new Ray(new Vector3(), new Vector3()),\r\n hoverInteraction: false,\r\n nearInteraction: false,\r\n grabInteraction: false,\r\n id: WebXRNearInteraction._idCounter++,\r\n pickedPointVisualCue: selectionMesh,\r\n };\r\n\r\n if (this._attachedController) {\r\n if (\r\n !this._options.enableNearInteractionOnAllControllers &&\r\n this._options.preferredHandedness &&\r\n xrController.inputSource.handedness === this._options.preferredHandedness\r\n ) {\r\n this._attachedController = xrController.uniqueId;\r\n }\r\n } else {\r\n if (!this._options.enableNearInteractionOnAllControllers) {\r\n this._attachedController = xrController.uniqueId;\r\n }\r\n }\r\n switch (xrController.inputSource.targetRayMode) {\r\n case \"tracked-pointer\":\r\n return this._attachNearInteractionMode(xrController);\r\n case \"gaze\":\r\n return null;\r\n case \"screen\":\r\n return null;\r\n }\r\n };\r\n\r\n private _controllers: {\r\n [controllerUniqueId: string]: ControllerData;\r\n } = {};\r\n private _scene: Scene;\r\n\r\n private _attachedController: string;\r\n\r\n private _farInteractionFeature: Nullable<WebXRControllerPointerSelection> = null;\r\n\r\n /**\r\n * The module's name\r\n */\r\n public static readonly Name = WebXRFeatureName.NEAR_INTERACTION;\r\n /**\r\n * The (Babylon) version of this module.\r\n * This is an integer representing the implementation version.\r\n * This number does not correspond to the WebXR specs version\r\n */\r\n public static readonly Version = 1;\r\n\r\n /**\r\n * default color of the selection ring\r\n */\r\n public selectionMeshDefaultColor: Color3 = new Color3(0.8, 0.8, 0.8);\r\n /**\r\n * This color will be applied to the selection ring when selection is triggered\r\n */\r\n public selectionMeshPickedColor: Color3 = new Color3(0.3, 0.3, 1.0);\r\n\r\n /**\r\n * constructs a new background remover module\r\n * @param _xrSessionManager the session manager for this module\r\n * @param _options read-only options to be used in this module\r\n */\r\n constructor(_xrSessionManager: WebXRSessionManager, private readonly _options: IWebXRNearInteractionOptions) {\r\n super(_xrSessionManager);\r\n this._scene = this._xrSessionManager.scene;\r\n if (this._options.farInteractionFeature) {\r\n this._farInteractionFeature = this._options.farInteractionFeature;\r\n }\r\n }\r\n\r\n /**\r\n * Attach this feature\r\n * Will usually be called by the features manager\r\n *\r\n * @returns true if successful.\r\n */\r\n public attach(): boolean {\r\n if (!super.attach()) {\r\n return false;\r\n }\r\n\r\n this._options.xrInput.controllers.forEach(this._attachController);\r\n this._addNewAttachObserver(this._options.xrInput.onControllerAddedObservable, this._attachController);\r\n this._addNewAttachObserver(this._options.xrInput.onControllerRemovedObservable, (controller) => {\r\n // REMOVE the controller\r\n this._detachController(controller.uniqueId);\r\n });\r\n\r\n this._scene.constantlyUpdateMeshUnderPointer = true;\r\n return true;\r\n }\r\n\r\n /**\r\n * Detach this feature.\r\n * Will usually be called by the features manager\r\n *\r\n * @returns true if successful.\r\n */\r\n public detach(): boolean {\r\n if (!super.detach()) {\r\n return false;\r\n }\r\n\r\n Object.keys(this._controllers).forEach((controllerId) => {\r\n this._detachController(controllerId);\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Will get the mesh under a specific pointer.\r\n * `scene.meshUnderPointer` will only return one mesh - either left or right.\r\n * @param controllerId the controllerId to check\r\n * @returns The mesh under pointer or null if no mesh is under the pointer\r\n */\r\n public getMeshUnderPointer(controllerId: string): Nullable<AbstractMesh> {\r\n if (this._controllers[controllerId]) {\r\n return this._controllers[controllerId].meshUnderPointer;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Get the xr controller that correlates to the pointer id in the pointer event\r\n *\r\n * @param id the pointer id to search for\r\n * @returns the controller that correlates to this id or null if not found\r\n */\r\n public getXRControllerByPointerId(id: number): Nullable<WebXRInputSource> {\r\n const keys = Object.keys(this._controllers);\r\n\r\n for (let i = 0; i < keys.length; ++i) {\r\n if (this._controllers[keys[i]].id === id) {\r\n return this._controllers[keys[i]].xrController || null;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * This function sets webXRControllerPointerSelection feature that will be disabled when\r\n * the hover range is reached for a mesh and will be reattached when not in hover range.\r\n * This is used to remove the selection rays when moving.\r\n * @param farInteractionFeature the feature to disable when finger is in hover range for a mesh\r\n */\r\n public setFarInteractionFeature(farInteractionFeature: Nullable<WebXRControllerPointerSelection>) {\r\n this._farInteractionFeature = farInteractionFeature;\r\n }\r\n\r\n /**\r\n * Filter used for near interaction pick and hover\r\n */\r\n private _nearPickPredicate(mesh: AbstractMesh): boolean {\r\n return mesh.isEnabled() && mesh.isVisible && mesh.isPickable && mesh.isNearPickable;\r\n }\r\n\r\n /**\r\n * Filter used for near interaction grab\r\n */\r\n private _nearGrabPredicate(mesh: AbstractMesh): boolean {\r\n return mesh.isEnabled() && mesh.isVisible && mesh.isPickable && mesh.isNearGrabbable;\r\n }\r\n\r\n /**\r\n * Filter used for any near interaction\r\n */\r\n private _nearInteractionPredicate(mesh: AbstractMesh): boolean {\r\n return mesh.isEnabled() && mesh.isVisible && mesh.isPickable && (mesh.isNearPickable || mesh.isNearGrabbable);\r\n }\r\n\r\n private _controllerAvailablePredicate(mesh: AbstractMesh, controllerId: string): boolean {\r\n let parent: TransformNode = mesh;\r\n\r\n while (parent) {\r\n if (parent.reservedDataStore && parent.reservedDataStore.nearInteraction && parent.reservedDataStore.nearInteraction.excludedControllerId === controllerId) {\r\n return false;\r\n }\r\n parent = parent.parent as TransformNode;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private readonly _hoverRadius = 0.1;\r\n private readonly _pickRadius = 0.02;\r\n private readonly _nearGrabLengthScale = 5;\r\n private _indexTipQuaternion = new Quaternion();\r\n private _indexTipOrientationVector = Vector3.Zero();\r\n\r\n protected _onXRFrame(_xrFrame: XRFrame) {\r\n Object.keys(this._controllers).forEach((id) => {\r\n // only do this for the selected pointer\r\n const controllerData = this._controllers[id];\r\n // If near interaction is not enabled/available for this controller, return early\r\n if ((!this._options.enableNearInteractionOnAllControllers && id !== this._attachedController) ||\r\n !controllerData.xrController ||\r\n !controllerData.xrController.inputSource.hand) {\r\n controllerData.pick = null;\r\n return;\r\n }\r\n controllerData.hoverInteraction = false;\r\n controllerData.nearInteraction = false;\r\n\r\n // Every frame check collisions/input\r\n if (controllerData.xrController) {\r\n const hand = controllerData.xrController.inputSource.hand;\r\n if (hand) {\r\n const xrIndexTip = hand.get(\"index-finger-tip\");\r\n if (xrIndexTip) {\r\n let indexTipPose = _xrFrame.getJointPose!(xrIndexTip, this._xrSessionManager.referenceSpace);\r\n if (indexTipPose && indexTipPose.transform) {\r\n let axisRHSMultiplier = this._scene.useRightHandedSystem ? 1 : -1;\r\n const indexTipPos = indexTipPose.transform.position;\r\n const indexTipOrientation = indexTipPose.transform.orientation;\r\n this._indexTipQuaternion.set(\r\n indexTipOrientation.x,\r\n indexTipOrientation.y,\r\n indexTipOrientation.z * axisRHSMultiplier,\r\n indexTipOrientation.w * axisRHSMultiplier\r\n );\r\n\r\n // set positions for near pick and hover\r\n if (controllerData.pickIndexMeshTip) {\r\n controllerData.pickIndexMeshTip.position.set(indexTipPos.x, indexTipPos.y, indexTipPos.z * axisRHSMultiplier);\r\n }\r\n\r\n // set near interaction grab ray parameters\r\n const nearGrabRayLength = this._nearGrabLengthScale * this._hoverRadius;\r\n controllerData.grabRay.origin.set(indexTipPos.x, indexTipPos.y, indexTipPos.z * axisRHSMultiplier);\r\n this._indexTipQuaternion.toEulerAnglesToRef(this._indexTipOrientationVector);\r\n controllerData.grabRay.direction.set(this._indexTipOrientationVector.x, this._indexTipOrientationVector.y, this._indexTipOrientationVector.z);\r\n controllerData.grabRay.length = nearGrabRayLength;\r\n }\r\n }\r\n }\r\n } else {\r\n return;\r\n }\r\n\r\n let accuratePickInfo = (originalScenePick: Nullable<PickingInfo>, utilityScenePick: Nullable<PickingInfo>): Nullable<PickingInfo> => {\r\n let pick = null;\r\n if (!utilityScenePick || !utilityScenePick.hit) {\r\n // No hit in utility scene\r\n pick = originalScenePick;\r\n } else if (!originalScenePick || !originalScenePick.hit) {\r\n // No hit in original scene\r\n pick = utilityScenePick;\r\n } else if (utilityScenePick.distance < originalScenePick.distance) {\r\n // Hit is closer in utility scene\r\n pick = utilityScenePick;\r\n } else {\r\n // Hit is closer in original scene\r\n pick = originalScenePick;\r\n }\r\n return pick;\r\n };\r\n let populateNearInteractionInfo = (nearInteractionInfo: Nullable<PickingInfo>): PickingInfo => {\r\n let result = new PickingInfo();\r\n\r\n let nearInteractionAtOrigin = false;\r\n let nearInteraction = nearInteractionInfo && nearInteractionInfo.pickedPoint && nearInteractionInfo.hit;\r\n if (nearInteractionInfo?.pickedPoint) {\r\n nearInteractionAtOrigin = nearInteractionInfo.pickedPoint.x === 0 && nearInteractionInfo.pickedPoint.y === 0 && nearInteractionInfo.pickedPoint.z === 0;\r\n }\r\n if (nearInteraction && !nearInteractionAtOrigin) {\r\n result = nearInteractionInfo!;\r\n }\r\n return result;\r\n };\r\n\r\n // Don't perform touch logic while grabbing, to prevent triggering touch interactions while in the middle of a grab interaction\r\n // Dont update cursor logic either - the cursor should already be visible for the grab to be in range,\r\n // and in order to maintain its position on the target mesh it is parented for the duration of the grab.\r\n if (!controllerData.grabInteraction) {\r\n let pick = null;\r\n\r\n // near interaction hover\r\n let utilitySceneHoverPick = null;\r\n if (this._options.useUtilityLayer && this._utilityLayerScene) {\r\n utilitySceneHoverPick = this._pickWithSphere(controllerData, this._hoverRadius, this._utilityLayerScene, (mesh: AbstractMesh) =>\r\n this._nearInteractionPredicate(mesh)\r\n );\r\n }\r\n let originalSceneHoverPick = this._pickWithSphere(controllerData, this._hoverRadius, this._scene, (mesh: AbstractMesh) => this._nearInteractionPredicate(mesh));\r\n\r\n let hoverPickInfo = accuratePickInfo(originalSceneHoverPick, utilitySceneHoverPick);\r\n if (hoverPickInfo && hoverPickInfo.hit) {\r\n pick = populateNearInteractionInfo(hoverPickInfo);\r\n if (pick.hit) {\r\n controllerData.hoverInteraction = true;\r\n }\r\n }\r\n\r\n // near interaction pick\r\n if (controllerData.pickIndexMeshTip && controllerData.hoverInteraction) {\r\n let utilitySceneNearPick = null;\r\n if (this._options.useUtilityLayer && this._utilityLayerScene) {\r\n utilitySceneNearPick = this._pickWithSphere(controllerData, this._pickRadius, this._utilityLayerScene, (mesh: AbstractMesh) => this._nearPickPredicate(mesh));\r\n }\r\n let originalSceneNearPick = this._pickWithSphere(controllerData, this._pickRadius, this._scene, (mesh: AbstractMesh) => this._nearPickPredicate(mesh));\r\n let pickInfo = accuratePickInfo(originalSceneNearPick, utilitySceneNearPick);\r\n const nearPick = populateNearInteractionInfo(pickInfo);\r\n if (nearPick.hit) {\r\n // Near pick takes precedence over hover interaction\r\n pick = nearPick;\r\n controllerData.nearInteraction = true;\r\n }\r\n }\r\n\r\n controllerData.pick = pick;\r\n\r\n // Update mesh under pointer\r\n if (controllerData.pick && controllerData.pick.pickedPoint && controllerData.pick.hit) {\r\n controllerData.meshUnderPointer = controllerData.pick.pickedMesh;\r\n controllerData.pickedPointVisualCue.position.copyFrom(controllerData.pick.pickedPoint);\r\n controllerData.pickedPointVisualCue.isVisible = true;\r\n\r\n if (this._farInteractionFeature && this._farInteractionFeature.attached) {\r\n this._farInteractionFeature._setPointerSelectionDisabledByPointerId(controllerData.id, true);\r\n }\r\n } else {\r\n controllerData.meshUnderPointer = null;\r\n controllerData.pickedPointVisualCue.isVisible = false;\r\n\r\n if (this._farInteractionFeature && this._farInteractionFeature.attached) {\r\n this._farInteractionFeature._setPointerSelectionDisabledByPointerId(controllerData.id, false);\r\n }\r\n }\r\n }\r\n });\r\n }\r\n\r\n private get _utilityLayerScene() {\r\n return this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene;\r\n }\r\n\r\n private _generateVisualCue() {\r\n const sceneToRenderTo = this._options.useUtilityLayer ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene : this._scene;\r\n const selectionMesh = CreateSphere(\r\n \"nearInteraction\",\r\n {\r\n diameter: 0.0035 * 3,\r\n },\r\n sceneToRenderTo\r\n );\r\n selectionMesh.bakeCurrentTransformIntoVertices();\r\n selectionMesh.isPickable = false;\r\n selectionMesh.isVisible = false;\r\n selectionMesh.rotationQuaternion = Quaternion.Identity();\r\n let targetMat = new StandardMaterial(\"targetMat\", sceneToRenderTo);\r\n targetMat.specularColor = Color3.Black();\r\n targetMat.emissiveColor = this.selectionMeshDefaultColor;\r\n targetMat.backFaceCulling = false;\r\n selectionMesh.material = targetMat;\r\n\r\n return selectionMesh;\r\n }\r\n\r\n private _isControllerReadyForNearInteraction(id: number) {\r\n if (this._farInteractionFeature) {\r\n return this._farInteractionFeature._getPointerSelectionDisabledByPointerId(id);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _attachNearInteractionMode(xrController: WebXRInputSource) {\r\n const controllerData = this._controllers[xrController.uniqueId];\r\n const pointerEventInit: PointerEventInit = {\r\n pointerId: controllerData.id,\r\n pointerType: \"xr\",\r\n };\r\n controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {\r\n if ((!this._options.enableNearInteractionOnAllControllers && xrController.uniqueId !== this._attachedController) ||\r\n !controllerData.xrController ||\r\n !controllerData.xrController.inputSource.hand) {\r\n return;\r\n }\r\n if (controllerData.pick) {\r\n controllerData.pick.ray = controllerData.grabRay;\r\n }\r\n\r\n if (controllerData.pick && this._isControllerReadyForNearInteraction(controllerData.id)) {\r\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\r\n }\r\n\r\n // Near pick pointer event\r\n if (controllerData.nearInteraction && controllerData.pick && controllerData.pick.hit) {\r\n if (!controllerData.nearInteractionMesh) {\r\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n controllerData.nearInteractionMesh = controllerData.meshUnderPointer;\r\n }\r\n } else if (controllerData.nearInteractionMesh && controllerData.pick) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n controllerData.nearInteractionMesh = null;\r\n }\r\n });\r\n\r\n const grabCheck = (pressed: boolean) => {\r\n if (this._options.enableNearInteractionOnAllControllers || (xrController.uniqueId === this._attachedController && this._isControllerReadyForNearInteraction(controllerData.id))) {\r\n if (controllerData.pick) {\r\n controllerData.pick.ray = controllerData.grabRay;\r\n }\r\n if (pressed && controllerData.pick && controllerData.meshUnderPointer && this._nearGrabPredicate(controllerData.meshUnderPointer)) {\r\n controllerData.grabInteraction = true;\r\n controllerData.pickedPointVisualCue.isVisible = false;\r\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n } else if (!pressed && controllerData.pick && controllerData.grabInteraction) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n controllerData.grabInteraction = false;\r\n controllerData.pickedPointVisualCue.isVisible = true;\r\n }\r\n } else {\r\n if (pressed && !this._options.enableNearInteractionOnAllControllers && !this._options.disableSwitchOnClick) {\r\n this._attachedController = xrController.uniqueId;\r\n }\r\n }\r\n };\r\n\r\n if (xrController.inputSource.gamepad) {\r\n const init = (motionController: WebXRAbstractMotionController) => {\r\n controllerData.squeezeComponent = motionController.getComponent(\"grasp\");\r\n if (controllerData.squeezeComponent) {\r\n controllerData.onSqueezeButtonChangedObserver = controllerData.squeezeComponent.onButtonStateChangedObservable.add((component) => {\r\n if (component.changes.pressed) {\r\n const pressed = component.changes.pressed.current;\r\n grabCheck(pressed);\r\n }\r\n });\r\n } else {\r\n controllerData.selectionComponent = motionController.getMainComponent();\r\n controllerData.onButtonChangedObserver = controllerData.selectionComponent.onButtonStateChangedObservable.add((component) => {\r\n if (component.changes.pressed) {\r\n const pressed = component.changes.pressed.current;\r\n grabCheck(pressed);\r\n }\r\n });\r\n }\r\n };\r\n if (xrController.motionController) {\r\n init(xrController.motionController);\r\n } else {\r\n xrController.onMotionControllerInitObservable.add(init);\r\n }\r\n } else {\r\n // use the select and squeeze events\r\n const selectStartListener = (event: XRInputSourceEvent) => {\r\n if (\r\n controllerData.xrController &&\r\n event.inputSource === controllerData.xrController.inputSource &&\r\n controllerData.pick &&\r\n this._isControllerReadyForNearInteraction(controllerData.id) &&\r\n controllerData.meshUnderPointer &&\r\n this._nearGrabPredicate(controllerData.meshUnderPointer)\r\n ) {\r\n controllerData.grabInteraction = true;\r\n controllerData.pickedPointVisualCue.isVisible = false;\r\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n }\r\n };\r\n\r\n const selectEndListener = (event: XRInputSourceEvent) => {\r\n if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick && this._isControllerReadyForNearInteraction(controllerData.id)) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n controllerData.grabInteraction = false;\r\n controllerData.pickedPointVisualCue.isVisible = true;\r\n }\r\n };\r\n\r\n controllerData.eventListeners = {\r\n selectend: selectEndListener,\r\n selectstart: selectStartListener,\r\n };\r\n\r\n this._xrSessionManager.session.addEventListener(\"selectstart\", selectStartListener);\r\n this._xrSessionManager.session.addEventListener(\"selectend\", selectEndListener);\r\n }\r\n }\r\n\r\n private _detachController(xrControllerUniqueId: string) {\r\n const controllerData = this._controllers[xrControllerUniqueId];\r\n if (!controllerData) {\r\n return;\r\n }\r\n if (controllerData.squeezeComponent) {\r\n if (controllerData.onSqueezeButtonChangedObserver) {\r\n controllerData.squeezeComponent.onButtonStateChangedObservable.remove(controllerData.onSqueezeButtonChangedObserver);\r\n }\r\n }\r\n if (controllerData.selectionComponent) {\r\n if (controllerData.onButtonChangedObserver) {\r\n controllerData.selectionComponent.onButtonStateChangedObservable.remove(controllerData.onButtonChangedObserver);\r\n }\r\n }\r\n if (controllerData.onFrameObserver) {\r\n this._xrSessionManager.onXRFrameObservable.remove(controllerData.onFrameObserver);\r\n }\r\n if (controllerData.eventListeners) {\r\n Object.keys(controllerData.eventListeners).forEach((eventName: string) => {\r\n const func = controllerData.eventListeners && controllerData.eventListeners[eventName as XREventType];\r\n if (func) {\r\n this._xrSessionManager.session.removeEventListener(eventName as XREventType, func);\r\n }\r\n });\r\n }\r\n controllerData.pickIndexMeshTip?.dispose();\r\n controllerData.pickedPointVisualCue.dispose();\r\n\r\n // Fire a pointerup\r\n const pointerEventInit: PointerEventInit = {\r\n pointerId: controllerData.id,\r\n pointerType: \"xr\",\r\n };\r\n this._scene.simulatePointerUp(new PickingInfo(), pointerEventInit);\r\n\r\n // remove from the map\r\n delete this._controllers[xrControllerUniqueId];\r\n if (this._attachedController === xrControllerUniqueId) {\r\n // check for other controllers\r\n const keys = Object.keys(this._controllers);\r\n if (keys.length) {\r\n this._attachedController = keys[0];\r\n } else {\r\n this._attachedController = \"\";\r\n }\r\n }\r\n }\r\n\r\n private _generateNewHandTipMesh() {\r\n // populate information for near hover, pick and pinch\r\n const meshCreationScene = this._options.useUtilityLayer ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene : this._scene;\r\n var pickIndexMeshTip = null;\r\n\r\n let createSphereMesh = (name: string, scale: number, sceneToUse: Scene): Nullable<AbstractMesh> => {\r\n let resultMesh = null;\r\n resultMesh = CreateSphere(name, { diameter: 1 }, sceneToUse);\r\n resultMesh.scaling.set(scale, scale, scale);\r\n resultMesh.isVisible = false;\r\n\r\n return resultMesh;\r\n };\r\n\r\n pickIndexMeshTip = createSphereMesh(\"IndexPickSphere\", this._pickRadius, meshCreationScene);\r\n return pickIndexMeshTip;\r\n }\r\n\r\n private _pickWithSphere(controllerData: ControllerData, radius: number, sceneToUse: Scene, predicate: (mesh: AbstractMesh) => boolean): Nullable<PickingInfo> {\r\n let pickingInfo = new PickingInfo();\r\n pickingInfo.distance = +Infinity;\r\n\r\n if (controllerData.pickIndexMeshTip && controllerData.xrController) {\r\n const position = controllerData.pickIndexMeshTip.position;\r\n const sphere = BoundingSphere.CreateFromCenterAndRadius(position, radius);\r\n\r\n for (let meshIndex = 0; meshIndex < sceneToUse.meshes.length; meshIndex++) {\r\n let mesh = sceneToUse.meshes[meshIndex];\r\n if (!predicate(mesh) || !this._controllerAvailablePredicate(mesh, controllerData.xrController.uniqueId)) {\r\n continue;\r\n }\r\n let result = WebXRNearInteraction.PickMeshWithSphere(mesh, sphere);\r\n\r\n if (result && result.hit && result.distance < pickingInfo.distance) {\r\n pickingInfo.hit = result.hit;\r\n pickingInfo.pickedMesh = mesh;\r\n pickingInfo.pickedPoint = result.pickedPoint;\r\n pickingInfo.aimTransform = controllerData.xrController.pointer;\r\n pickingInfo.gripTransform = controllerData.xrController.grip || null;\r\n pickingInfo.originMesh = controllerData.pickIndexMeshTip;\r\n pickingInfo.distance = result.distance;\r\n }\r\n }\r\n }\r\n return pickingInfo;\r\n }\r\n\r\n /**\r\n * Picks a mesh with a sphere\r\n * @param mesh the mesh to pick\r\n * @param sphere picking sphere in world coordinates\r\n * @param skipBoundingInfo a boolean indicating if we should skip the bounding info check\r\n * @returns the picking info\r\n */\r\n public static PickMeshWithSphere(mesh: AbstractMesh, sphere: BoundingSphere, skipBoundingInfo = false): PickingInfo {\r\n const subMeshes = mesh.subMeshes;\r\n const pi = new PickingInfo();\r\n const boundingInfo = mesh.getBoundingInfo();\r\n\r\n if (!mesh._generatePointsArray()) {\r\n return pi;\r\n }\r\n\r\n if (!mesh.subMeshes || !boundingInfo) {\r\n return pi;\r\n }\r\n\r\n if (!skipBoundingInfo && !BoundingSphere.Intersects(boundingInfo.boundingSphere, sphere)) {\r\n return pi;\r\n }\r\n\r\n const result = TmpVectors.Vector3[0];\r\n const tmpVec = TmpVectors.Vector3[1];\r\n\r\n let distance = +Infinity;\r\n let tmp, tmpDistanceSphereToCenter, tmpDistanceSurfaceToCenter;\r\n const center = TmpVectors.Vector3[2];\r\n const worldToMesh = TmpVectors.Matrix[0];\r\n worldToMesh.copyFrom(mesh.getWorldMatrix());\r\n worldToMesh.invert();\r\n Vector3.TransformCoordinatesToRef(sphere.center, worldToMesh, center);\r\n\r\n for (var index = 0; index < subMeshes.length; index++) {\r\n const subMesh = subMeshes[index];\r\n\r\n subMesh.projectToRef(center, <Vector3[]>mesh._positions, <IndicesArray>mesh.getIndices(), tmpVec);\r\n\r\n Vector3.TransformCoordinatesToRef(tmpVec, mesh.getWorldMatrix(), tmpVec);\r\n tmp = Vector3.Distance(tmpVec, sphere.center);\r\n\r\n // Check for finger inside of mesh\r\n tmpDistanceSurfaceToCenter = Vector3.Distance(tmpVec, mesh.getAbsolutePosition());\r\n tmpDistanceSphereToCenter = Vector3.Distance(sphere.center, mesh.getAbsolutePosition());\r\n if (tmpDistanceSphereToCenter !== -1 && tmpDistanceSurfaceToCenter !== -1 && tmpDistanceSurfaceToCenter > tmpDistanceSphereToCenter) {\r\n tmp = 0;\r\n tmpVec.copyFrom(sphere.center);\r\n }\r\n\r\n if (tmp !== -1 && tmp < distance) {\r\n distance = tmp;\r\n result.copyFrom(tmpVec);\r\n }\r\n }\r\n\r\n if (distance < sphere.radius) {\r\n pi.hit = true;\r\n pi.distance = distance;\r\n pi.pickedMesh = mesh;\r\n pi.pickedPoint = result.clone();\r\n }\r\n\r\n return pi;\r\n }\r\n}\r\n\r\n//Register the plugin\r\nWebXRFeaturesManager.AddWebXRFeature(\r\n WebXRNearInteraction.Name,\r\n (xrSessionManager, options) => {\r\n return () => new WebXRNearInteraction(xrSessionManager, options);\r\n },\r\n WebXRNearInteraction.Version,\r\n true\r\n);\r\n"]}
1
+ {"version":3,"file":"WebXRNearInteraction.js","sourceRoot":"","sources":["../../../../sourceES6/core/XR/features/WebXRNearInteraction.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebXRFeaturesManager, WebXRFeatureName } from \"../webXRFeaturesManager\";\r\nimport { WebXRControllerPointerSelection } from \"./WebXRControllerPointerSelection\";\r\nimport { WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { CreateSphere } from \"../../Meshes/Builders/sphereBuilder\";\r\nimport { Observer } from \"../../Misc/observable\";\r\nimport { WebXRInput } from \"../webXRInput\";\r\nimport { WebXRInputSource } from \"../webXRInputSource\";\r\nimport { Scene } from \"../../scene\";\r\nimport { WebXRControllerComponent } from \"../motionController/webXRControllerComponent\";\r\nimport { IndicesArray, Nullable } from \"../../types\";\r\nimport { Vector3, Quaternion, TmpVectors } from \"../../Maths/math.vector\";\r\nimport { Ray } from \"../../Culling/ray\";\r\nimport { PickingInfo } from \"../../Collisions/pickingInfo\";\r\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { UtilityLayerRenderer } from \"../../Rendering/utilityLayerRenderer\";\r\nimport { WebXRAbstractMotionController } from \"../motionController/webXRAbstractMotionController\";\r\nimport { BoundingSphere } from \"../../Culling/boundingSphere\";\r\nimport { TransformNode } from \"../../Meshes/transformNode\";\r\nimport { StandardMaterial } from \"../../Materials/standardMaterial\";\r\nimport { Color3 } from \"../../Maths/math.color\";\r\n// side effects\r\nimport \"../../Meshes/subMesh.project\";\r\n\r\ntype ControllerData = {\r\n xrController?: WebXRInputSource;\r\n squeezeComponent?: WebXRControllerComponent;\r\n selectionComponent?: WebXRControllerComponent;\r\n onButtonChangedObserver?: Nullable<Observer<WebXRControllerComponent>>;\r\n onSqueezeButtonChangedObserver?: Nullable<Observer<WebXRControllerComponent>>;\r\n onFrameObserver?: Nullable<Observer<XRFrame>>;\r\n meshUnderPointer: Nullable<AbstractMesh>;\r\n nearInteractionMesh: Nullable<AbstractMesh>;\r\n pick: Nullable<PickingInfo>;\r\n id: number;\r\n pickIndexMeshTip: Nullable<AbstractMesh>;\r\n grabRay: Ray;\r\n nearInteraction: boolean;\r\n hoverInteraction: boolean;\r\n grabInteraction: boolean;\r\n // event support\r\n eventListeners?: { [event in XREventType]?: (event: XRInputSourceEvent) => void };\r\n pickedPointVisualCue: AbstractMesh;\r\n};\r\n\r\n/**\r\n * Options interface for the near interaction module\r\n */\r\nexport interface IWebXRNearInteractionOptions {\r\n /**\r\n * If provided, this scene will be used to render meshes.\r\n */\r\n customUtilityLayerScene?: Scene;\r\n /**\r\n * Should meshes created here be added to a utility layer or the main scene\r\n */\r\n useUtilityLayer?: boolean;\r\n /**\r\n * The xr input to use with this near interaction\r\n */\r\n xrInput: WebXRInput;\r\n /**\r\n * Enable near interaction on all controllers instead of switching between them\r\n */\r\n enableNearInteractionOnAllControllers?: boolean;\r\n /**\r\n * The preferred hand to give the near interaction to. This will be prioritized when the controller initialize.\r\n * If switch is enabled, it will still allow the user to switch between the different controllers\r\n */\r\n preferredHandedness?: XRHandedness;\r\n /**\r\n * Disable switching the near interaction from one controller to the other.\r\n * If the preferred hand is set it will be fixed on this hand, and if not it will be fixed on the first controller added to the scene\r\n */\r\n disableSwitchOnClick?: boolean;\r\n\r\n /**\r\n * Far interaction feature to toggle when near interaction takes precedence\r\n */\r\n farInteractionFeature?: WebXRControllerPointerSelection;\r\n}\r\n\r\n/**\r\n * A module that will enable near interaction near interaction for hands and motion controllers of XR Input Sources\r\n */\r\nexport class WebXRNearInteraction extends WebXRAbstractFeature {\r\n private static _idCounter = 200;\r\n\r\n private _attachController = (xrController: WebXRInputSource) => {\r\n if (this._controllers[xrController.uniqueId]) {\r\n // already attached\r\n return;\r\n }\r\n // get two new meshes\r\n const pickIndexMeshTip = this._generateNewHandTipMesh();\r\n const selectionMesh = this._generateVisualCue();\r\n\r\n this._controllers[xrController.uniqueId] = {\r\n xrController,\r\n meshUnderPointer: null,\r\n nearInteractionMesh: null,\r\n pick: null,\r\n pickIndexMeshTip,\r\n grabRay: new Ray(new Vector3(), new Vector3()),\r\n hoverInteraction: false,\r\n nearInteraction: false,\r\n grabInteraction: false,\r\n id: WebXRNearInteraction._idCounter++,\r\n pickedPointVisualCue: selectionMesh,\r\n };\r\n\r\n if (this._attachedController) {\r\n if (\r\n !this._options.enableNearInteractionOnAllControllers &&\r\n this._options.preferredHandedness &&\r\n xrController.inputSource.handedness === this._options.preferredHandedness\r\n ) {\r\n this._attachedController = xrController.uniqueId;\r\n }\r\n } else {\r\n if (!this._options.enableNearInteractionOnAllControllers) {\r\n this._attachedController = xrController.uniqueId;\r\n }\r\n }\r\n switch (xrController.inputSource.targetRayMode) {\r\n case \"tracked-pointer\":\r\n return this._attachNearInteractionMode(xrController);\r\n case \"gaze\":\r\n return null;\r\n case \"screen\":\r\n return null;\r\n }\r\n };\r\n\r\n private _controllers: {\r\n [controllerUniqueId: string]: ControllerData;\r\n } = {};\r\n private _scene: Scene;\r\n\r\n private _attachedController: string;\r\n\r\n private _farInteractionFeature: Nullable<WebXRControllerPointerSelection> = null;\r\n\r\n /**\r\n * The module's name\r\n */\r\n public static readonly Name = WebXRFeatureName.NEAR_INTERACTION;\r\n /**\r\n * The (Babylon) version of this module.\r\n * This is an integer representing the implementation version.\r\n * This number does not correspond to the WebXR specs version\r\n */\r\n public static readonly Version = 1;\r\n\r\n /**\r\n * default color of the selection ring\r\n */\r\n public selectionMeshDefaultColor: Color3 = new Color3(0.8, 0.8, 0.8);\r\n /**\r\n * This color will be applied to the selection ring when selection is triggered\r\n */\r\n public selectionMeshPickedColor: Color3 = new Color3(0.3, 0.3, 1.0);\r\n\r\n /**\r\n * constructs a new background remover module\r\n * @param _xrSessionManager the session manager for this module\r\n * @param _options read-only options to be used in this module\r\n */\r\n constructor(_xrSessionManager: WebXRSessionManager, private readonly _options: IWebXRNearInteractionOptions) {\r\n super(_xrSessionManager);\r\n this._scene = this._xrSessionManager.scene;\r\n if (this._options.farInteractionFeature) {\r\n this._farInteractionFeature = this._options.farInteractionFeature;\r\n }\r\n }\r\n\r\n /**\r\n * Attach this feature\r\n * Will usually be called by the features manager\r\n *\r\n * @returns true if successful.\r\n */\r\n public attach(): boolean {\r\n if (!super.attach()) {\r\n return false;\r\n }\r\n\r\n this._options.xrInput.controllers.forEach(this._attachController);\r\n this._addNewAttachObserver(this._options.xrInput.onControllerAddedObservable, this._attachController);\r\n this._addNewAttachObserver(this._options.xrInput.onControllerRemovedObservable, (controller) => {\r\n // REMOVE the controller\r\n this._detachController(controller.uniqueId);\r\n });\r\n\r\n this._scene.constantlyUpdateMeshUnderPointer = true;\r\n return true;\r\n }\r\n\r\n /**\r\n * Detach this feature.\r\n * Will usually be called by the features manager\r\n *\r\n * @returns true if successful.\r\n */\r\n public detach(): boolean {\r\n if (!super.detach()) {\r\n return false;\r\n }\r\n\r\n Object.keys(this._controllers).forEach((controllerId) => {\r\n this._detachController(controllerId);\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Will get the mesh under a specific pointer.\r\n * `scene.meshUnderPointer` will only return one mesh - either left or right.\r\n * @param controllerId the controllerId to check\r\n * @returns The mesh under pointer or null if no mesh is under the pointer\r\n */\r\n public getMeshUnderPointer(controllerId: string): Nullable<AbstractMesh> {\r\n if (this._controllers[controllerId]) {\r\n return this._controllers[controllerId].meshUnderPointer;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Get the xr controller that correlates to the pointer id in the pointer event\r\n *\r\n * @param id the pointer id to search for\r\n * @returns the controller that correlates to this id or null if not found\r\n */\r\n public getXRControllerByPointerId(id: number): Nullable<WebXRInputSource> {\r\n const keys = Object.keys(this._controllers);\r\n\r\n for (let i = 0; i < keys.length; ++i) {\r\n if (this._controllers[keys[i]].id === id) {\r\n return this._controllers[keys[i]].xrController || null;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * This function sets webXRControllerPointerSelection feature that will be disabled when\r\n * the hover range is reached for a mesh and will be reattached when not in hover range.\r\n * This is used to remove the selection rays when moving.\r\n * @param farInteractionFeature the feature to disable when finger is in hover range for a mesh\r\n */\r\n public setFarInteractionFeature(farInteractionFeature: Nullable<WebXRControllerPointerSelection>) {\r\n this._farInteractionFeature = farInteractionFeature;\r\n }\r\n\r\n /**\r\n * Filter used for near interaction pick and hover\r\n */\r\n private _nearPickPredicate(mesh: AbstractMesh): boolean {\r\n return mesh.isEnabled() && mesh.isVisible && mesh.isPickable && mesh.isNearPickable;\r\n }\r\n\r\n /**\r\n * Filter used for near interaction grab\r\n */\r\n private _nearGrabPredicate(mesh: AbstractMesh): boolean {\r\n return mesh.isEnabled() && mesh.isVisible && mesh.isPickable && mesh.isNearGrabbable;\r\n }\r\n\r\n /**\r\n * Filter used for any near interaction\r\n */\r\n private _nearInteractionPredicate(mesh: AbstractMesh): boolean {\r\n return mesh.isEnabled() && mesh.isVisible && mesh.isPickable && (mesh.isNearPickable || mesh.isNearGrabbable);\r\n }\r\n\r\n private _controllerAvailablePredicate(mesh: AbstractMesh, controllerId: string): boolean {\r\n let parent: TransformNode = mesh;\r\n\r\n while (parent) {\r\n if (parent.reservedDataStore && parent.reservedDataStore.nearInteraction && parent.reservedDataStore.nearInteraction.excludedControllerId === controllerId) {\r\n return false;\r\n }\r\n parent = parent.parent as TransformNode;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private readonly _hoverRadius = 0.1;\r\n private readonly _pickRadius = 0.02;\r\n private readonly _nearGrabLengthScale = 5;\r\n private _indexTipQuaternion = new Quaternion();\r\n private _indexTipOrientationVector = Vector3.Zero();\r\n\r\n protected _onXRFrame(_xrFrame: XRFrame) {\r\n Object.keys(this._controllers).forEach((id) => {\r\n // only do this for the selected pointer\r\n const controllerData = this._controllers[id];\r\n // If near interaction is not enabled/available for this controller, return early\r\n if ((!this._options.enableNearInteractionOnAllControllers && id !== this._attachedController) ||\r\n !controllerData.xrController ||\r\n !controllerData.xrController.inputSource.hand) {\r\n controllerData.pick = null;\r\n return;\r\n }\r\n controllerData.hoverInteraction = false;\r\n controllerData.nearInteraction = false;\r\n\r\n // Every frame check collisions/input\r\n if (controllerData.xrController) {\r\n const hand = controllerData.xrController.inputSource.hand;\r\n if (hand) {\r\n const xrIndexTip = hand.get(\"index-finger-tip\");\r\n if (xrIndexTip) {\r\n let indexTipPose = _xrFrame.getJointPose!(xrIndexTip, this._xrSessionManager.referenceSpace);\r\n if (indexTipPose && indexTipPose.transform) {\r\n let axisRHSMultiplier = this._scene.useRightHandedSystem ? 1 : -1;\r\n const indexTipPos = indexTipPose.transform.position;\r\n const indexTipOrientation = indexTipPose.transform.orientation;\r\n this._indexTipQuaternion.set(\r\n indexTipOrientation.x,\r\n indexTipOrientation.y,\r\n indexTipOrientation.z * axisRHSMultiplier,\r\n indexTipOrientation.w * axisRHSMultiplier\r\n );\r\n\r\n // set positions for near pick and hover\r\n if (controllerData.pickIndexMeshTip) {\r\n controllerData.pickIndexMeshTip.position.set(indexTipPos.x, indexTipPos.y, indexTipPos.z * axisRHSMultiplier);\r\n }\r\n\r\n // set near interaction grab ray parameters\r\n const nearGrabRayLength = this._nearGrabLengthScale * this._hoverRadius;\r\n controllerData.grabRay.origin.set(indexTipPos.x, indexTipPos.y, indexTipPos.z * axisRHSMultiplier);\r\n this._indexTipQuaternion.toEulerAnglesToRef(this._indexTipOrientationVector);\r\n controllerData.grabRay.direction.set(this._indexTipOrientationVector.x, this._indexTipOrientationVector.y, this._indexTipOrientationVector.z);\r\n controllerData.grabRay.length = nearGrabRayLength;\r\n }\r\n }\r\n }\r\n } else {\r\n return;\r\n }\r\n\r\n let accuratePickInfo = (originalScenePick: Nullable<PickingInfo>, utilityScenePick: Nullable<PickingInfo>): Nullable<PickingInfo> => {\r\n let pick = null;\r\n if (!utilityScenePick || !utilityScenePick.hit) {\r\n // No hit in utility scene\r\n pick = originalScenePick;\r\n } else if (!originalScenePick || !originalScenePick.hit) {\r\n // No hit in original scene\r\n pick = utilityScenePick;\r\n } else if (utilityScenePick.distance < originalScenePick.distance) {\r\n // Hit is closer in utility scene\r\n pick = utilityScenePick;\r\n } else {\r\n // Hit is closer in original scene\r\n pick = originalScenePick;\r\n }\r\n return pick;\r\n };\r\n let populateNearInteractionInfo = (nearInteractionInfo: Nullable<PickingInfo>): PickingInfo => {\r\n let result = new PickingInfo();\r\n\r\n let nearInteractionAtOrigin = false;\r\n let nearInteraction = nearInteractionInfo && nearInteractionInfo.pickedPoint && nearInteractionInfo.hit;\r\n if (nearInteractionInfo?.pickedPoint) {\r\n nearInteractionAtOrigin = nearInteractionInfo.pickedPoint.x === 0 && nearInteractionInfo.pickedPoint.y === 0 && nearInteractionInfo.pickedPoint.z === 0;\r\n }\r\n if (nearInteraction && !nearInteractionAtOrigin) {\r\n result = nearInteractionInfo!;\r\n }\r\n return result;\r\n };\r\n\r\n // Don't perform touch logic while grabbing, to prevent triggering touch interactions while in the middle of a grab interaction\r\n // Dont update cursor logic either - the cursor should already be visible for the grab to be in range,\r\n // and in order to maintain its position on the target mesh it is parented for the duration of the grab.\r\n if (!controllerData.grabInteraction) {\r\n let pick = null;\r\n\r\n // near interaction hover\r\n let utilitySceneHoverPick = null;\r\n if (this._options.useUtilityLayer && this._utilityLayerScene) {\r\n utilitySceneHoverPick = this._pickWithSphere(controllerData, this._hoverRadius, this._utilityLayerScene, (mesh: AbstractMesh) =>\r\n this._nearInteractionPredicate(mesh)\r\n );\r\n }\r\n let originalSceneHoverPick = this._pickWithSphere(controllerData, this._hoverRadius, this._scene, (mesh: AbstractMesh) => this._nearInteractionPredicate(mesh));\r\n\r\n let hoverPickInfo = accuratePickInfo(originalSceneHoverPick, utilitySceneHoverPick);\r\n if (hoverPickInfo && hoverPickInfo.hit) {\r\n pick = populateNearInteractionInfo(hoverPickInfo);\r\n if (pick.hit) {\r\n controllerData.hoverInteraction = true;\r\n }\r\n }\r\n\r\n // near interaction pick\r\n if (controllerData.pickIndexMeshTip && controllerData.hoverInteraction) {\r\n let utilitySceneNearPick = null;\r\n if (this._options.useUtilityLayer && this._utilityLayerScene) {\r\n utilitySceneNearPick = this._pickWithSphere(controllerData, this._pickRadius, this._utilityLayerScene, (mesh: AbstractMesh) => this._nearPickPredicate(mesh));\r\n }\r\n let originalSceneNearPick = this._pickWithSphere(controllerData, this._pickRadius, this._scene, (mesh: AbstractMesh) => this._nearPickPredicate(mesh));\r\n let pickInfo = accuratePickInfo(originalSceneNearPick, utilitySceneNearPick);\r\n const nearPick = populateNearInteractionInfo(pickInfo);\r\n if (nearPick.hit) {\r\n // Near pick takes precedence over hover interaction\r\n pick = nearPick;\r\n controllerData.nearInteraction = true;\r\n }\r\n }\r\n\r\n controllerData.pick = pick;\r\n\r\n // Update mesh under pointer\r\n if (controllerData.pick && controllerData.pick.pickedPoint && controllerData.pick.hit) {\r\n controllerData.meshUnderPointer = controllerData.pick.pickedMesh;\r\n controllerData.pickedPointVisualCue.position.copyFrom(controllerData.pick.pickedPoint);\r\n controllerData.pickedPointVisualCue.isVisible = true;\r\n\r\n if (this._farInteractionFeature && this._farInteractionFeature.attached) {\r\n this._farInteractionFeature._setPointerSelectionDisabledByPointerId(controllerData.id, true);\r\n }\r\n } else {\r\n controllerData.meshUnderPointer = null;\r\n controllerData.pickedPointVisualCue.isVisible = false;\r\n\r\n if (this._farInteractionFeature && this._farInteractionFeature.attached) {\r\n this._farInteractionFeature._setPointerSelectionDisabledByPointerId(controllerData.id, false);\r\n }\r\n }\r\n }\r\n });\r\n }\r\n\r\n private get _utilityLayerScene() {\r\n return this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene;\r\n }\r\n\r\n private _generateVisualCue() {\r\n const sceneToRenderTo = this._options.useUtilityLayer ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene : this._scene;\r\n const selectionMesh = CreateSphere(\r\n \"nearInteraction\",\r\n {\r\n diameter: 0.0035 * 3,\r\n },\r\n sceneToRenderTo\r\n );\r\n selectionMesh.bakeCurrentTransformIntoVertices();\r\n selectionMesh.isPickable = false;\r\n selectionMesh.isVisible = false;\r\n selectionMesh.rotationQuaternion = Quaternion.Identity();\r\n let targetMat = new StandardMaterial(\"targetMat\", sceneToRenderTo);\r\n targetMat.specularColor = Color3.Black();\r\n targetMat.emissiveColor = this.selectionMeshDefaultColor;\r\n targetMat.backFaceCulling = false;\r\n selectionMesh.material = targetMat;\r\n\r\n return selectionMesh;\r\n }\r\n\r\n private _isControllerReadyForNearInteraction(id: number) {\r\n if (this._farInteractionFeature) {\r\n return this._farInteractionFeature._getPointerSelectionDisabledByPointerId(id);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _attachNearInteractionMode(xrController: WebXRInputSource) {\r\n const controllerData = this._controllers[xrController.uniqueId];\r\n const pointerEventInit: PointerEventInit = {\r\n pointerId: controllerData.id,\r\n pointerType: \"xr\",\r\n };\r\n controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {\r\n if ((!this._options.enableNearInteractionOnAllControllers && xrController.uniqueId !== this._attachedController) ||\r\n !controllerData.xrController ||\r\n !controllerData.xrController.inputSource.hand) {\r\n return;\r\n }\r\n if (controllerData.pick) {\r\n controllerData.pick.ray = controllerData.grabRay;\r\n }\r\n\r\n if (controllerData.pick && this._isControllerReadyForNearInteraction(controllerData.id)) {\r\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\r\n }\r\n\r\n // Near pick pointer event\r\n if (controllerData.nearInteraction && controllerData.pick && controllerData.pick.hit) {\r\n if (!controllerData.nearInteractionMesh) {\r\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n controllerData.nearInteractionMesh = controllerData.meshUnderPointer;\r\n }\r\n } else if (controllerData.nearInteractionMesh && controllerData.pick) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n controllerData.nearInteractionMesh = null;\r\n }\r\n });\r\n\r\n const grabCheck = (pressed: boolean) => {\r\n if (this._options.enableNearInteractionOnAllControllers || (xrController.uniqueId === this._attachedController && this._isControllerReadyForNearInteraction(controllerData.id))) {\r\n if (controllerData.pick) {\r\n controllerData.pick.ray = controllerData.grabRay;\r\n }\r\n if (pressed && controllerData.pick && controllerData.meshUnderPointer && this._nearGrabPredicate(controllerData.meshUnderPointer)) {\r\n controllerData.grabInteraction = true;\r\n controllerData.pickedPointVisualCue.isVisible = false;\r\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n } else if (!pressed && controllerData.pick && controllerData.grabInteraction) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n controllerData.grabInteraction = false;\r\n controllerData.pickedPointVisualCue.isVisible = true;\r\n }\r\n } else {\r\n if (pressed && !this._options.enableNearInteractionOnAllControllers && !this._options.disableSwitchOnClick) {\r\n this._attachedController = xrController.uniqueId;\r\n }\r\n }\r\n };\r\n\r\n if (xrController.inputSource.gamepad) {\r\n const init = (motionController: WebXRAbstractMotionController) => {\r\n controllerData.squeezeComponent = motionController.getComponent(\"grasp\");\r\n if (controllerData.squeezeComponent) {\r\n controllerData.onSqueezeButtonChangedObserver = controllerData.squeezeComponent.onButtonStateChangedObservable.add((component) => {\r\n if (component.changes.pressed) {\r\n const pressed = component.changes.pressed.current;\r\n grabCheck(pressed);\r\n }\r\n });\r\n } else {\r\n controllerData.selectionComponent = motionController.getMainComponent();\r\n controllerData.onButtonChangedObserver = controllerData.selectionComponent.onButtonStateChangedObservable.add((component) => {\r\n if (component.changes.pressed) {\r\n const pressed = component.changes.pressed.current;\r\n grabCheck(pressed);\r\n }\r\n });\r\n }\r\n };\r\n if (xrController.motionController) {\r\n init(xrController.motionController);\r\n } else {\r\n xrController.onMotionControllerInitObservable.add(init);\r\n }\r\n } else {\r\n // use the select and squeeze events\r\n const selectStartListener = (event: XRInputSourceEvent) => {\r\n if (\r\n controllerData.xrController &&\r\n event.inputSource === controllerData.xrController.inputSource &&\r\n controllerData.pick &&\r\n this._isControllerReadyForNearInteraction(controllerData.id) &&\r\n controllerData.meshUnderPointer &&\r\n this._nearGrabPredicate(controllerData.meshUnderPointer)\r\n ) {\r\n controllerData.grabInteraction = true;\r\n controllerData.pickedPointVisualCue.isVisible = false;\r\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n }\r\n };\r\n\r\n const selectEndListener = (event: XRInputSourceEvent) => {\r\n if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick && this._isControllerReadyForNearInteraction(controllerData.id)) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n controllerData.grabInteraction = false;\r\n controllerData.pickedPointVisualCue.isVisible = true;\r\n }\r\n };\r\n\r\n controllerData.eventListeners = {\r\n selectend: selectEndListener,\r\n selectstart: selectStartListener,\r\n };\r\n\r\n this._xrSessionManager.session.addEventListener(\"selectstart\", selectStartListener);\r\n this._xrSessionManager.session.addEventListener(\"selectend\", selectEndListener);\r\n }\r\n }\r\n\r\n private _detachController(xrControllerUniqueId: string) {\r\n const controllerData = this._controllers[xrControllerUniqueId];\r\n if (!controllerData) {\r\n return;\r\n }\r\n if (controllerData.squeezeComponent) {\r\n if (controllerData.onSqueezeButtonChangedObserver) {\r\n controllerData.squeezeComponent.onButtonStateChangedObservable.remove(controllerData.onSqueezeButtonChangedObserver);\r\n }\r\n }\r\n if (controllerData.selectionComponent) {\r\n if (controllerData.onButtonChangedObserver) {\r\n controllerData.selectionComponent.onButtonStateChangedObservable.remove(controllerData.onButtonChangedObserver);\r\n }\r\n }\r\n if (controllerData.onFrameObserver) {\r\n this._xrSessionManager.onXRFrameObservable.remove(controllerData.onFrameObserver);\r\n }\r\n if (controllerData.eventListeners) {\r\n Object.keys(controllerData.eventListeners).forEach((eventName: string) => {\r\n const func = controllerData.eventListeners && controllerData.eventListeners[eventName as XREventType];\r\n if (func) {\r\n this._xrSessionManager.session.removeEventListener(eventName as XREventType, func);\r\n }\r\n });\r\n }\r\n controllerData.pickIndexMeshTip?.dispose();\r\n controllerData.pickedPointVisualCue.dispose();\r\n\r\n this._xrSessionManager.runInXRFrame(() => {\r\n // Fire a pointerup\r\n const pointerEventInit: PointerEventInit = {\r\n pointerId: controllerData.id,\r\n pointerType: \"xr\",\r\n };\r\n this._scene.simulatePointerUp(new PickingInfo(), pointerEventInit);\r\n });\r\n\r\n // remove from the map\r\n delete this._controllers[xrControllerUniqueId];\r\n if (this._attachedController === xrControllerUniqueId) {\r\n // check for other controllers\r\n const keys = Object.keys(this._controllers);\r\n if (keys.length) {\r\n this._attachedController = keys[0];\r\n } else {\r\n this._attachedController = \"\";\r\n }\r\n }\r\n }\r\n\r\n private _generateNewHandTipMesh() {\r\n // populate information for near hover, pick and pinch\r\n const meshCreationScene = this._options.useUtilityLayer ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene : this._scene;\r\n var pickIndexMeshTip = null;\r\n\r\n let createSphereMesh = (name: string, scale: number, sceneToUse: Scene): Nullable<AbstractMesh> => {\r\n let resultMesh = null;\r\n resultMesh = CreateSphere(name, { diameter: 1 }, sceneToUse);\r\n resultMesh.scaling.set(scale, scale, scale);\r\n resultMesh.isVisible = false;\r\n\r\n return resultMesh;\r\n };\r\n\r\n pickIndexMeshTip = createSphereMesh(\"IndexPickSphere\", this._pickRadius, meshCreationScene);\r\n return pickIndexMeshTip;\r\n }\r\n\r\n private _pickWithSphere(controllerData: ControllerData, radius: number, sceneToUse: Scene, predicate: (mesh: AbstractMesh) => boolean): Nullable<PickingInfo> {\r\n let pickingInfo = new PickingInfo();\r\n pickingInfo.distance = +Infinity;\r\n\r\n if (controllerData.pickIndexMeshTip && controllerData.xrController) {\r\n const position = controllerData.pickIndexMeshTip.position;\r\n const sphere = BoundingSphere.CreateFromCenterAndRadius(position, radius);\r\n\r\n for (let meshIndex = 0; meshIndex < sceneToUse.meshes.length; meshIndex++) {\r\n let mesh = sceneToUse.meshes[meshIndex];\r\n if (!predicate(mesh) || !this._controllerAvailablePredicate(mesh, controllerData.xrController.uniqueId)) {\r\n continue;\r\n }\r\n let result = WebXRNearInteraction.PickMeshWithSphere(mesh, sphere);\r\n\r\n if (result && result.hit && result.distance < pickingInfo.distance) {\r\n pickingInfo.hit = result.hit;\r\n pickingInfo.pickedMesh = mesh;\r\n pickingInfo.pickedPoint = result.pickedPoint;\r\n pickingInfo.aimTransform = controllerData.xrController.pointer;\r\n pickingInfo.gripTransform = controllerData.xrController.grip || null;\r\n pickingInfo.originMesh = controllerData.pickIndexMeshTip;\r\n pickingInfo.distance = result.distance;\r\n }\r\n }\r\n }\r\n return pickingInfo;\r\n }\r\n\r\n /**\r\n * Picks a mesh with a sphere\r\n * @param mesh the mesh to pick\r\n * @param sphere picking sphere in world coordinates\r\n * @param skipBoundingInfo a boolean indicating if we should skip the bounding info check\r\n * @returns the picking info\r\n */\r\n public static PickMeshWithSphere(mesh: AbstractMesh, sphere: BoundingSphere, skipBoundingInfo = false): PickingInfo {\r\n const subMeshes = mesh.subMeshes;\r\n const pi = new PickingInfo();\r\n const boundingInfo = mesh.getBoundingInfo();\r\n\r\n if (!mesh._generatePointsArray()) {\r\n return pi;\r\n }\r\n\r\n if (!mesh.subMeshes || !boundingInfo) {\r\n return pi;\r\n }\r\n\r\n if (!skipBoundingInfo && !BoundingSphere.Intersects(boundingInfo.boundingSphere, sphere)) {\r\n return pi;\r\n }\r\n\r\n const result = TmpVectors.Vector3[0];\r\n const tmpVec = TmpVectors.Vector3[1];\r\n\r\n let distance = +Infinity;\r\n let tmp, tmpDistanceSphereToCenter, tmpDistanceSurfaceToCenter;\r\n const center = TmpVectors.Vector3[2];\r\n const worldToMesh = TmpVectors.Matrix[0];\r\n worldToMesh.copyFrom(mesh.getWorldMatrix());\r\n worldToMesh.invert();\r\n Vector3.TransformCoordinatesToRef(sphere.center, worldToMesh, center);\r\n\r\n for (var index = 0; index < subMeshes.length; index++) {\r\n const subMesh = subMeshes[index];\r\n\r\n subMesh.projectToRef(center, <Vector3[]>mesh._positions, <IndicesArray>mesh.getIndices(), tmpVec);\r\n\r\n Vector3.TransformCoordinatesToRef(tmpVec, mesh.getWorldMatrix(), tmpVec);\r\n tmp = Vector3.Distance(tmpVec, sphere.center);\r\n\r\n // Check for finger inside of mesh\r\n tmpDistanceSurfaceToCenter = Vector3.Distance(tmpVec, mesh.getAbsolutePosition());\r\n tmpDistanceSphereToCenter = Vector3.Distance(sphere.center, mesh.getAbsolutePosition());\r\n if (tmpDistanceSphereToCenter !== -1 && tmpDistanceSurfaceToCenter !== -1 && tmpDistanceSurfaceToCenter > tmpDistanceSphereToCenter) {\r\n tmp = 0;\r\n tmpVec.copyFrom(sphere.center);\r\n }\r\n\r\n if (tmp !== -1 && tmp < distance) {\r\n distance = tmp;\r\n result.copyFrom(tmpVec);\r\n }\r\n }\r\n\r\n if (distance < sphere.radius) {\r\n pi.hit = true;\r\n pi.distance = distance;\r\n pi.pickedMesh = mesh;\r\n pi.pickedPoint = result.clone();\r\n }\r\n\r\n return pi;\r\n }\r\n}\r\n\r\n//Register the plugin\r\nWebXRFeaturesManager.AddWebXRFeature(\r\n WebXRNearInteraction.Name,\r\n (xrSessionManager, options) => {\r\n return () => new WebXRNearInteraction(xrSessionManager, options);\r\n },\r\n WebXRNearInteraction.Version,\r\n true\r\n);\r\n"]}
@@ -151,8 +151,15 @@ var WebXRExperienceHelper = /** @class */ (function () {
151
151
  // Kept here, TODO - check if needed
152
152
  this.scene.autoClear = false;
153
153
  this.camera.compensateOnFirstFrame = false;
154
+ // reset the camera's position to the origin
155
+ this.camera.position.set(0, 0, 0);
156
+ this.camera.rotationQuaternion.set(0, 0, 0, 1);
154
157
  }
155
158
  this.sessionManager.onXRSessionEnded.addOnce(function () {
159
+ // when using the back button and not the exit button (default on mobile), the session is ending but the EXITING state was not set
160
+ if (_this.state !== WebXRState.EXITING_XR) {
161
+ _this._setState(WebXRState.EXITING_XR);
162
+ }
156
163
  // Reset camera rigs output render target to ensure sessions render target is not drawn after it ends
157
164
  _this.camera.rigCameras.forEach(function (c) {
158
165
  c.outputRenderTarget = null;
@@ -1 +1 @@
1
- {"version":3,"file":"webXRExperienceHelper.js","sourceRoot":"","sources":["../../../sourceES6/core/XR/webXRExperienceHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import { Nullable } from \"../types\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { IDisposable, Scene } from \"../scene\";\r\nimport { Camera } from \"../Cameras/camera\";\r\nimport { WebXRSessionManager } from \"./webXRSessionManager\";\r\nimport { WebXRCamera } from \"./webXRCamera\";\r\nimport { WebXRState, WebXRRenderTarget } from \"./webXRTypes\";\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"./webXRFeaturesManager\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { UniversalCamera } from \"../Cameras/universalCamera\";\r\nimport { Quaternion, Vector3 } from \"../Maths/math.vector\";\r\n\r\n/**\r\n * Base set of functionality needed to create an XR experience (WebXRSessionManager, Camera, StateManagement, etc.)\r\n * @see https://doc.babylonjs.com/how_to/webxr_experience_helpers\r\n */\r\nexport class WebXRExperienceHelper implements IDisposable {\r\n private _nonVRCamera: Nullable<Camera> = null;\r\n private _attachedToElement: boolean = false;\r\n private _spectatorCamera: Nullable<UniversalCamera> = null;\r\n private _originalSceneAutoClear = true;\r\n private _supported = false;\r\n private _spectatorMode = false;\r\n\r\n /**\r\n * Camera used to render xr content\r\n */\r\n public camera: WebXRCamera;\r\n /** A features manager for this xr session */\r\n public featuresManager: WebXRFeaturesManager;\r\n /**\r\n * Observers registered here will be triggered after the camera's initial transformation is set\r\n * This can be used to set a different ground level or an extra rotation.\r\n *\r\n * Note that ground level is considered to be at 0. The height defined by the XR camera will be added\r\n * to the position set after this observable is done executing.\r\n */\r\n public onInitialXRPoseSetObservable = new Observable<WebXRCamera>();\r\n /**\r\n * Fires when the state of the experience helper has changed\r\n */\r\n public onStateChangedObservable = new Observable<WebXRState>();\r\n /** Session manager used to keep track of xr session */\r\n public sessionManager: WebXRSessionManager;\r\n /**\r\n * The current state of the XR experience (eg. transitioning, in XR or not in XR)\r\n */\r\n public state: WebXRState = WebXRState.NOT_IN_XR;\r\n\r\n /**\r\n * Creates a WebXRExperienceHelper\r\n * @param scene The scene the helper should be created in\r\n */\r\n private constructor(private scene: Scene) {\r\n this.sessionManager = new WebXRSessionManager(scene);\r\n this.camera = new WebXRCamera(\"webxr\", scene, this.sessionManager);\r\n this.featuresManager = new WebXRFeaturesManager(this.sessionManager);\r\n\r\n scene.onDisposeObservable.add(() => {\r\n this.exitXRAsync();\r\n });\r\n }\r\n\r\n /**\r\n * Creates the experience helper\r\n * @param scene the scene to attach the experience helper to\r\n * @returns a promise for the experience helper\r\n */\r\n public static CreateAsync(scene: Scene): Promise<WebXRExperienceHelper> {\r\n var helper = new WebXRExperienceHelper(scene);\r\n return helper.sessionManager\r\n .initializeAsync()\r\n .then(() => {\r\n helper._supported = true;\r\n return helper;\r\n })\r\n .catch((e) => {\r\n helper._setState(WebXRState.NOT_IN_XR);\r\n helper.dispose();\r\n throw e;\r\n });\r\n }\r\n\r\n /**\r\n * Disposes of the experience helper\r\n */\r\n public dispose() {\r\n this.camera.dispose();\r\n this.onStateChangedObservable.clear();\r\n this.onInitialXRPoseSetObservable.clear();\r\n this.sessionManager.dispose();\r\n this._spectatorCamera?.dispose();\r\n if (this._nonVRCamera) {\r\n this.scene.activeCamera = this._nonVRCamera;\r\n }\r\n }\r\n\r\n /**\r\n * Enters XR mode (This must be done within a user interaction in most browsers eg. button click)\r\n * @param sessionMode options for the XR session\r\n * @param referenceSpaceType frame of reference of the XR session\r\n * @param renderTarget the output canvas that will be used to enter XR mode\r\n * @param sessionCreationOptions optional XRSessionInit object to init the session with\r\n * @returns promise that resolves after xr mode has entered\r\n */\r\n public async enterXRAsync(sessionMode: XRSessionMode, referenceSpaceType: XRReferenceSpaceType, renderTarget: WebXRRenderTarget = this.sessionManager.getWebXRRenderTarget(), sessionCreationOptions: XRSessionInit = {}): Promise<WebXRSessionManager> {\r\n if (!this._supported) {\r\n throw \"WebXR not supported in this browser or environment\";\r\n }\r\n this._setState(WebXRState.ENTERING_XR);\r\n if (referenceSpaceType !== \"viewer\" && referenceSpaceType !== \"local\") {\r\n sessionCreationOptions.optionalFeatures = sessionCreationOptions.optionalFeatures || [];\r\n sessionCreationOptions.optionalFeatures.push(referenceSpaceType);\r\n }\r\n sessionCreationOptions = await this.featuresManager._extendXRSessionInitObject(sessionCreationOptions);\r\n // we currently recommend \"unbounded\" space in AR (#7959)\r\n if (sessionMode === \"immersive-ar\" && referenceSpaceType !== \"unbounded\") {\r\n Logger.Warn(\"We recommend using 'unbounded' reference space type when using 'immersive-ar' session mode\");\r\n }\r\n // make sure that the session mode is supported\r\n try {\r\n await this.sessionManager.initializeSessionAsync(sessionMode, sessionCreationOptions);\r\n await this.sessionManager.setReferenceSpaceTypeAsync(referenceSpaceType);\r\n const baseLayer = await renderTarget.initializeXRLayerAsync(this.sessionManager.session);\r\n\r\n const xrRenderState: XRRenderStateInit = {\r\n depthFar: this.camera.maxZ,\r\n depthNear: this.camera.minZ,\r\n };\r\n\r\n // The layers feature will have already initialized the xr session's layers on session init.\r\n if (!this.featuresManager.getEnabledFeature(WebXRFeatureName.LAYERS)) {\r\n xrRenderState.baseLayer = baseLayer;\r\n }\r\n\r\n this.sessionManager.updateRenderState(xrRenderState);\r\n // run the render loop\r\n this.sessionManager.runXRRenderLoop();\r\n // Cache pre xr scene settings\r\n this._originalSceneAutoClear = this.scene.autoClear;\r\n this._nonVRCamera = this.scene.activeCamera;\r\n this._attachedToElement = !!(this._nonVRCamera?.inputs.attachedToElement);\r\n this._nonVRCamera?.detachControl();\r\n\r\n this.scene.activeCamera = this.camera;\r\n // do not compensate when AR session is used\r\n if (sessionMode !== \"immersive-ar\") {\r\n this._nonXRToXRCamera();\r\n } else {\r\n // Kept here, TODO - check if needed\r\n this.scene.autoClear = false;\r\n this.camera.compensateOnFirstFrame = false;\r\n }\r\n\r\n this.sessionManager.onXRSessionEnded.addOnce(() => {\r\n // Reset camera rigs output render target to ensure sessions render target is not drawn after it ends\r\n this.camera.rigCameras.forEach((c) => {\r\n c.outputRenderTarget = null;\r\n });\r\n\r\n // Restore scene settings\r\n this.scene.autoClear = this._originalSceneAutoClear;\r\n this.scene.activeCamera = this._nonVRCamera;\r\n if (this._attachedToElement && this._nonVRCamera) {\r\n this._nonVRCamera.attachControl(!!(this._nonVRCamera.inputs.noPreventDefault));\r\n }\r\n if (sessionMode !== \"immersive-ar\" && this.camera.compensateOnFirstFrame) {\r\n if ((<any>this._nonVRCamera).setPosition) {\r\n (<any>this._nonVRCamera).setPosition(this.camera.position);\r\n } else {\r\n this._nonVRCamera!.position.copyFrom(this.camera.position);\r\n }\r\n }\r\n\r\n this._setState(WebXRState.NOT_IN_XR);\r\n });\r\n\r\n // Wait until the first frame arrives before setting state to in xr\r\n this.sessionManager.onXRFrameObservable.addOnce(() => {\r\n this._setState(WebXRState.IN_XR);\r\n });\r\n return this.sessionManager;\r\n } catch (e) {\r\n console.log(e);\r\n console.log(e.message);\r\n this._setState(WebXRState.NOT_IN_XR);\r\n throw e;\r\n }\r\n }\r\n\r\n /**\r\n * Exits XR mode and returns the scene to its original state\r\n * @returns promise that resolves after xr mode has exited\r\n */\r\n public exitXRAsync() {\r\n // only exit if state is IN_XR\r\n if (this.state !== WebXRState.IN_XR) {\r\n return Promise.resolve();\r\n }\r\n this._setState(WebXRState.EXITING_XR);\r\n return this.sessionManager.exitXRAsync();\r\n }\r\n\r\n /**\r\n * Enable spectator mode for desktop VR experiences.\r\n * When spectator mode is enabled a camera will be attached to the desktop canvas and will\r\n * display the first rig camera's view on the desktop canvas.\r\n * Please note that this will degrade performance, as it requires another camera render.\r\n * It is also not recommended to enable this in devices like the quest, as it brings no benefit there.\r\n */\r\n public enableSpectatorMode(): void {\r\n if (!this._spectatorMode) {\r\n const updateSpectatorCamera = () => {\r\n if (this._spectatorCamera) {\r\n this._spectatorCamera.position.copyFrom(this.camera.rigCameras[0].globalPosition);\r\n this._spectatorCamera.rotationQuaternion.copyFrom(this.camera.rigCameras[0].absoluteRotation);\r\n }\r\n };\r\n const onStateChanged = () => {\r\n if (this.state === WebXRState.IN_XR) {\r\n this._spectatorCamera = new UniversalCamera('webxr-spectator', Vector3.Zero(), this.scene);\r\n this._spectatorCamera.rotationQuaternion = new Quaternion();\r\n this.scene.activeCameras = [this.camera, this._spectatorCamera];\r\n this.sessionManager.onXRFrameObservable.add(updateSpectatorCamera);\r\n this.scene.onAfterRenderCameraObservable.add((camera) => {\r\n if (camera === this.camera) {\r\n // reset the dimensions object for correct resizing\r\n this.scene.getEngine().framebufferDimensionsObject = null;\r\n }\r\n });\r\n } else if (this.state === WebXRState.EXITING_XR) {\r\n this.sessionManager.onXRFrameObservable.removeCallback(updateSpectatorCamera);\r\n this.scene.activeCameras = null;\r\n }\r\n };\r\n this._spectatorMode = true;\r\n this.onStateChangedObservable.add(onStateChanged);\r\n onStateChanged();\r\n }\r\n }\r\n\r\n private _nonXRToXRCamera() {\r\n this.camera.setTransformationFromNonVRCamera(this._nonVRCamera!);\r\n this.onInitialXRPoseSetObservable.notifyObservers(this.camera);\r\n }\r\n\r\n private _setState(val: WebXRState) {\r\n if (this.state === val) {\r\n return;\r\n }\r\n this.state = val;\r\n this.onStateChangedObservable.notifyObservers(this.state);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"webXRExperienceHelper.js","sourceRoot":"","sources":["../../../sourceES6/core/XR/webXRExperienceHelper.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAqB,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE3D;;;GAGG;AACH;IAiCI;;;OAGG;IACH,+BAA4B,KAAY;QAAxC,iBAQC;QAR2B,UAAK,GAAL,KAAK,CAAO;QApChC,iBAAY,GAAqB,IAAI,CAAC;QACtC,uBAAkB,GAAY,KAAK,CAAC;QACpC,qBAAgB,GAA8B,IAAI,CAAC;QACnD,4BAAuB,GAAG,IAAI,CAAC;QAC/B,eAAU,GAAG,KAAK,CAAC;QACnB,mBAAc,GAAG,KAAK,CAAC;QAQ/B;;;;;;WAMG;QACI,iCAA4B,GAAG,IAAI,UAAU,EAAe,CAAC;QACpE;;WAEG;QACI,6BAAwB,GAAG,IAAI,UAAU,EAAc,CAAC;QAG/D;;WAEG;QACI,UAAK,GAAe,UAAU,CAAC,SAAS,CAAC;QAO5C,IAAI,CAAC,cAAc,GAAG,IAAI,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,CAAC,MAAM,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACnE,IAAI,CAAC,eAAe,GAAG,IAAI,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAErE,KAAK,CAAC,mBAAmB,CAAC,GAAG,CAAC;YAC1B,KAAI,CAAC,WAAW,EAAE,CAAC;QACvB,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;;OAIG;IACW,iCAAW,GAAzB,UAA0B,KAAY;QAClC,IAAI,MAAM,GAAG,IAAI,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAC9C,OAAO,MAAM,CAAC,cAAc;aACvB,eAAe,EAAE;aACjB,IAAI,CAAC;YACF,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;YACzB,OAAO,MAAM,CAAC;QAClB,CAAC,CAAC;aACD,KAAK,CAAC,UAAC,CAAC;YACL,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,CAAC,CAAC;QACZ,CAAC,CAAC,CAAC;IACX,CAAC;IAED;;OAEG;IACI,uCAAO,GAAd;;QACI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,wBAAwB,CAAC,KAAK,EAAE,CAAC;QACtC,IAAI,CAAC,4BAA4B,CAAC,KAAK,EAAE,CAAC;QAC1C,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;QAC9B,MAAA,IAAI,CAAC,gBAAgB,0CAAE,OAAO,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,YAAY,EAAE;YACnB,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;SAC/C;IACL,CAAC;IAED;;;;;;;OAOG;IACU,4CAAY,GAAzB,UAA0B,WAA0B,EAAE,kBAAwC,EAAE,YAA4E,EAAE,sBAA0C;;QAAxH,6BAAA,EAAA,eAAkC,IAAI,CAAC,cAAc,CAAC,oBAAoB,EAAE;QAAE,uCAAA,EAAA,2BAA0C;;;;;;;wBACpN,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;4BAClB,MAAM,oDAAoD,CAAC;yBAC9D;wBACD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;wBACvC,IAAI,kBAAkB,KAAK,QAAQ,IAAI,kBAAkB,KAAK,OAAO,EAAE;4BACnE,sBAAsB,CAAC,gBAAgB,GAAG,sBAAsB,CAAC,gBAAgB,IAAI,EAAE,CAAC;4BACxF,sBAAsB,CAAC,gBAAgB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;yBACpE;wBACwB,qBAAM,IAAI,CAAC,eAAe,CAAC,0BAA0B,CAAC,sBAAsB,CAAC,EAAA;;wBAAtG,sBAAsB,GAAG,SAA6E,CAAC;wBACvG,yDAAyD;wBACzD,IAAI,WAAW,KAAK,cAAc,IAAI,kBAAkB,KAAK,WAAW,EAAE;4BACtE,MAAM,CAAC,IAAI,CAAC,4FAA4F,CAAC,CAAC;yBAC7G;;;;wBAGG,qBAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,CAAC,WAAW,EAAE,sBAAsB,CAAC,EAAA;;wBAArF,SAAqF,CAAC;wBACtF,qBAAM,IAAI,CAAC,cAAc,CAAC,0BAA0B,CAAC,kBAAkB,CAAC,EAAA;;wBAAxE,SAAwE,CAAC;wBACvD,qBAAM,YAAY,CAAC,sBAAsB,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAA;;wBAAlF,SAAS,GAAG,SAAsE;wBAElF,aAAa,GAAsB;4BACrC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;4BAC1B,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;yBAC9B,CAAC;wBAEF,4FAA4F;wBAC5F,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE;4BAClE,aAAa,CAAC,SAAS,GAAG,SAAS,CAAC;yBACvC;wBAED,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;wBACrD,sBAAsB;wBACtB,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC;wBACtC,8BAA8B;wBAC9B,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;wBACpD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC;wBAC5C,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC,MAAA,IAAI,CAAC,YAAY,0CAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC;wBAC1E,MAAA,IAAI,CAAC,YAAY,0CAAE,aAAa,EAAE,CAAC;wBAEnC,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;wBACtC,4CAA4C;wBAC5C,IAAI,WAAW,KAAK,cAAc,EAAE;4BAChC,IAAI,CAAC,gBAAgB,EAAE,CAAC;yBAC3B;6BAAM;4BACH,oCAAoC;4BACpC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC;4BAC7B,IAAI,CAAC,MAAM,CAAC,sBAAsB,GAAG,KAAK,CAAC;4BAC3C,4CAA4C;4BAC5C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;4BAClC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;yBAClD;wBAED,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,OAAO,CAAC;4BACzC,kIAAkI;4BAClI,IAAI,KAAI,CAAC,KAAK,KAAK,UAAU,CAAC,UAAU,EAAE;gCACtC,KAAI,CAAC,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;6BACzC;4BACD,qGAAqG;4BACrG,KAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,UAAC,CAAC;gCAC7B,CAAC,CAAC,kBAAkB,GAAG,IAAI,CAAC;4BAChC,CAAC,CAAC,CAAC;4BAEH,yBAAyB;4BACzB,KAAI,CAAC,KAAK,CAAC,SAAS,GAAG,KAAI,CAAC,uBAAuB,CAAC;4BACpD,KAAI,CAAC,KAAK,CAAC,YAAY,GAAG,KAAI,CAAC,YAAY,CAAC;4BAC5C,IAAI,KAAI,CAAC,kBAAkB,IAAI,KAAI,CAAC,YAAY,EAAE;gCAC9C,KAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KAAI,CAAC,YAAY,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC;6BAClF;4BACD,IAAI,WAAW,KAAK,cAAc,IAAI,KAAI,CAAC,MAAM,CAAC,sBAAsB,EAAE;gCACtE,IAAU,KAAI,CAAC,YAAa,CAAC,WAAW,EAAE;oCAChC,KAAI,CAAC,YAAa,CAAC,WAAW,CAAC,KAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;iCAC9D;qCAAM;oCACH,KAAI,CAAC,YAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;iCAC9D;6BACJ;4BAED,KAAI,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;wBACzC,CAAC,CAAC,CAAC;wBAEH,mEAAmE;wBACnE,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC,OAAO,CAAC;4BAC5C,KAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;wBACrC,CAAC,CAAC,CAAC;wBACH,sBAAO,IAAI,CAAC,cAAc,EAAC;;;wBAE3B,OAAO,CAAC,GAAG,CAAC,GAAC,CAAC,CAAC;wBACf,OAAO,CAAC,GAAG,CAAC,GAAC,CAAC,OAAO,CAAC,CAAC;wBACvB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;wBACrC,MAAM,GAAC,CAAC;;;;;KAEf;IAED;;;OAGG;IACI,2CAAW,GAAlB;QACI,8BAA8B;QAC9B,IAAI,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,EAAE;YACjC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;SAC5B;QACD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC;IAC7C,CAAC;IAED;;;;;;OAMG;IACI,mDAAmB,GAA1B;QAAA,iBA6BC;QA5BG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;YACtB,IAAM,uBAAqB,GAAG;gBAC1B,IAAI,KAAI,CAAC,gBAAgB,EAAE;oBACvB,KAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;oBAClF,KAAI,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,QAAQ,CAAC,KAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;iBACjG;YACL,CAAC,CAAC;YACF,IAAM,cAAc,GAAG;gBACnB,IAAI,KAAI,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,EAAE;oBACjC,KAAI,CAAC,gBAAgB,GAAG,IAAI,eAAe,CAAC,iBAAiB,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,KAAI,CAAC,KAAK,CAAC,CAAC;oBAC3F,KAAI,CAAC,gBAAgB,CAAC,kBAAkB,GAAG,IAAI,UAAU,EAAE,CAAC;oBAC5D,KAAI,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,KAAI,CAAC,MAAM,EAAE,KAAI,CAAC,gBAAgB,CAAC,CAAC;oBAChE,KAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC,GAAG,CAAC,uBAAqB,CAAC,CAAC;oBACnE,KAAI,CAAC,KAAK,CAAC,6BAA6B,CAAC,GAAG,CAAC,UAAC,MAAM;wBAChD,IAAI,MAAM,KAAK,KAAI,CAAC,MAAM,EAAE;4BACxB,mDAAmD;4BACnD,KAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,2BAA2B,GAAG,IAAI,CAAC;yBAC7D;oBACL,CAAC,CAAC,CAAC;iBACN;qBAAM,IAAI,KAAI,CAAC,KAAK,KAAK,UAAU,CAAC,UAAU,EAAE;oBAC7C,KAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC,cAAc,CAAC,uBAAqB,CAAC,CAAC;oBAC9E,KAAI,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;iBACnC;YACL,CAAC,CAAC;YACF,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAClD,cAAc,EAAE,CAAC;SACpB;IACL,CAAC;IAEO,gDAAgB,GAAxB;QACI,IAAI,CAAC,MAAM,CAAC,gCAAgC,CAAC,IAAI,CAAC,YAAa,CAAC,CAAC;QACjE,IAAI,CAAC,4BAA4B,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnE,CAAC;IAEO,yCAAS,GAAjB,UAAkB,GAAe;QAC7B,IAAI,IAAI,CAAC,KAAK,KAAK,GAAG,EAAE;YACpB,OAAO;SACV;QACD,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC;QACjB,IAAI,CAAC,wBAAwB,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9D,CAAC;IACL,4BAAC;AAAD,CAAC,AApPD,IAoPC","sourcesContent":["import { Nullable } from \"../types\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { IDisposable, Scene } from \"../scene\";\r\nimport { Camera } from \"../Cameras/camera\";\r\nimport { WebXRSessionManager } from \"./webXRSessionManager\";\r\nimport { WebXRCamera } from \"./webXRCamera\";\r\nimport { WebXRState, WebXRRenderTarget } from \"./webXRTypes\";\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"./webXRFeaturesManager\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { UniversalCamera } from \"../Cameras/universalCamera\";\r\nimport { Quaternion, Vector3 } from \"../Maths/math.vector\";\r\n\r\n/**\r\n * Base set of functionality needed to create an XR experience (WebXRSessionManager, Camera, StateManagement, etc.)\r\n * @see https://doc.babylonjs.com/how_to/webxr_experience_helpers\r\n */\r\nexport class WebXRExperienceHelper implements IDisposable {\r\n private _nonVRCamera: Nullable<Camera> = null;\r\n private _attachedToElement: boolean = false;\r\n private _spectatorCamera: Nullable<UniversalCamera> = null;\r\n private _originalSceneAutoClear = true;\r\n private _supported = false;\r\n private _spectatorMode = false;\r\n\r\n /**\r\n * Camera used to render xr content\r\n */\r\n public camera: WebXRCamera;\r\n /** A features manager for this xr session */\r\n public featuresManager: WebXRFeaturesManager;\r\n /**\r\n * Observers registered here will be triggered after the camera's initial transformation is set\r\n * This can be used to set a different ground level or an extra rotation.\r\n *\r\n * Note that ground level is considered to be at 0. The height defined by the XR camera will be added\r\n * to the position set after this observable is done executing.\r\n */\r\n public onInitialXRPoseSetObservable = new Observable<WebXRCamera>();\r\n /**\r\n * Fires when the state of the experience helper has changed\r\n */\r\n public onStateChangedObservable = new Observable<WebXRState>();\r\n /** Session manager used to keep track of xr session */\r\n public sessionManager: WebXRSessionManager;\r\n /**\r\n * The current state of the XR experience (eg. transitioning, in XR or not in XR)\r\n */\r\n public state: WebXRState = WebXRState.NOT_IN_XR;\r\n\r\n /**\r\n * Creates a WebXRExperienceHelper\r\n * @param scene The scene the helper should be created in\r\n */\r\n private constructor(private scene: Scene) {\r\n this.sessionManager = new WebXRSessionManager(scene);\r\n this.camera = new WebXRCamera(\"webxr\", scene, this.sessionManager);\r\n this.featuresManager = new WebXRFeaturesManager(this.sessionManager);\r\n\r\n scene.onDisposeObservable.add(() => {\r\n this.exitXRAsync();\r\n });\r\n }\r\n\r\n /**\r\n * Creates the experience helper\r\n * @param scene the scene to attach the experience helper to\r\n * @returns a promise for the experience helper\r\n */\r\n public static CreateAsync(scene: Scene): Promise<WebXRExperienceHelper> {\r\n var helper = new WebXRExperienceHelper(scene);\r\n return helper.sessionManager\r\n .initializeAsync()\r\n .then(() => {\r\n helper._supported = true;\r\n return helper;\r\n })\r\n .catch((e) => {\r\n helper._setState(WebXRState.NOT_IN_XR);\r\n helper.dispose();\r\n throw e;\r\n });\r\n }\r\n\r\n /**\r\n * Disposes of the experience helper\r\n */\r\n public dispose() {\r\n this.camera.dispose();\r\n this.onStateChangedObservable.clear();\r\n this.onInitialXRPoseSetObservable.clear();\r\n this.sessionManager.dispose();\r\n this._spectatorCamera?.dispose();\r\n if (this._nonVRCamera) {\r\n this.scene.activeCamera = this._nonVRCamera;\r\n }\r\n }\r\n\r\n /**\r\n * Enters XR mode (This must be done within a user interaction in most browsers eg. button click)\r\n * @param sessionMode options for the XR session\r\n * @param referenceSpaceType frame of reference of the XR session\r\n * @param renderTarget the output canvas that will be used to enter XR mode\r\n * @param sessionCreationOptions optional XRSessionInit object to init the session with\r\n * @returns promise that resolves after xr mode has entered\r\n */\r\n public async enterXRAsync(sessionMode: XRSessionMode, referenceSpaceType: XRReferenceSpaceType, renderTarget: WebXRRenderTarget = this.sessionManager.getWebXRRenderTarget(), sessionCreationOptions: XRSessionInit = {}): Promise<WebXRSessionManager> {\r\n if (!this._supported) {\r\n throw \"WebXR not supported in this browser or environment\";\r\n }\r\n this._setState(WebXRState.ENTERING_XR);\r\n if (referenceSpaceType !== \"viewer\" && referenceSpaceType !== \"local\") {\r\n sessionCreationOptions.optionalFeatures = sessionCreationOptions.optionalFeatures || [];\r\n sessionCreationOptions.optionalFeatures.push(referenceSpaceType);\r\n }\r\n sessionCreationOptions = await this.featuresManager._extendXRSessionInitObject(sessionCreationOptions);\r\n // we currently recommend \"unbounded\" space in AR (#7959)\r\n if (sessionMode === \"immersive-ar\" && referenceSpaceType !== \"unbounded\") {\r\n Logger.Warn(\"We recommend using 'unbounded' reference space type when using 'immersive-ar' session mode\");\r\n }\r\n // make sure that the session mode is supported\r\n try {\r\n await this.sessionManager.initializeSessionAsync(sessionMode, sessionCreationOptions);\r\n await this.sessionManager.setReferenceSpaceTypeAsync(referenceSpaceType);\r\n const baseLayer = await renderTarget.initializeXRLayerAsync(this.sessionManager.session);\r\n\r\n const xrRenderState: XRRenderStateInit = {\r\n depthFar: this.camera.maxZ,\r\n depthNear: this.camera.minZ,\r\n };\r\n\r\n // The layers feature will have already initialized the xr session's layers on session init.\r\n if (!this.featuresManager.getEnabledFeature(WebXRFeatureName.LAYERS)) {\r\n xrRenderState.baseLayer = baseLayer;\r\n }\r\n\r\n this.sessionManager.updateRenderState(xrRenderState);\r\n // run the render loop\r\n this.sessionManager.runXRRenderLoop();\r\n // Cache pre xr scene settings\r\n this._originalSceneAutoClear = this.scene.autoClear;\r\n this._nonVRCamera = this.scene.activeCamera;\r\n this._attachedToElement = !!(this._nonVRCamera?.inputs.attachedToElement);\r\n this._nonVRCamera?.detachControl();\r\n\r\n this.scene.activeCamera = this.camera;\r\n // do not compensate when AR session is used\r\n if (sessionMode !== \"immersive-ar\") {\r\n this._nonXRToXRCamera();\r\n } else {\r\n // Kept here, TODO - check if needed\r\n this.scene.autoClear = false;\r\n this.camera.compensateOnFirstFrame = false;\r\n // reset the camera's position to the origin\r\n this.camera.position.set(0, 0, 0);\r\n this.camera.rotationQuaternion.set(0, 0, 0, 1);\r\n }\r\n\r\n this.sessionManager.onXRSessionEnded.addOnce(() => {\r\n // when using the back button and not the exit button (default on mobile), the session is ending but the EXITING state was not set\r\n if (this.state !== WebXRState.EXITING_XR) {\r\n this._setState(WebXRState.EXITING_XR);\r\n }\r\n // Reset camera rigs output render target to ensure sessions render target is not drawn after it ends\r\n this.camera.rigCameras.forEach((c) => {\r\n c.outputRenderTarget = null;\r\n });\r\n\r\n // Restore scene settings\r\n this.scene.autoClear = this._originalSceneAutoClear;\r\n this.scene.activeCamera = this._nonVRCamera;\r\n if (this._attachedToElement && this._nonVRCamera) {\r\n this._nonVRCamera.attachControl(!!(this._nonVRCamera.inputs.noPreventDefault));\r\n }\r\n if (sessionMode !== \"immersive-ar\" && this.camera.compensateOnFirstFrame) {\r\n if ((<any>this._nonVRCamera).setPosition) {\r\n (<any>this._nonVRCamera).setPosition(this.camera.position);\r\n } else {\r\n this._nonVRCamera!.position.copyFrom(this.camera.position);\r\n }\r\n }\r\n\r\n this._setState(WebXRState.NOT_IN_XR);\r\n });\r\n\r\n // Wait until the first frame arrives before setting state to in xr\r\n this.sessionManager.onXRFrameObservable.addOnce(() => {\r\n this._setState(WebXRState.IN_XR);\r\n });\r\n return this.sessionManager;\r\n } catch (e) {\r\n console.log(e);\r\n console.log(e.message);\r\n this._setState(WebXRState.NOT_IN_XR);\r\n throw e;\r\n }\r\n }\r\n\r\n /**\r\n * Exits XR mode and returns the scene to its original state\r\n * @returns promise that resolves after xr mode has exited\r\n */\r\n public exitXRAsync() {\r\n // only exit if state is IN_XR\r\n if (this.state !== WebXRState.IN_XR) {\r\n return Promise.resolve();\r\n }\r\n this._setState(WebXRState.EXITING_XR);\r\n return this.sessionManager.exitXRAsync();\r\n }\r\n\r\n /**\r\n * Enable spectator mode for desktop VR experiences.\r\n * When spectator mode is enabled a camera will be attached to the desktop canvas and will\r\n * display the first rig camera's view on the desktop canvas.\r\n * Please note that this will degrade performance, as it requires another camera render.\r\n * It is also not recommended to enable this in devices like the quest, as it brings no benefit there.\r\n */\r\n public enableSpectatorMode(): void {\r\n if (!this._spectatorMode) {\r\n const updateSpectatorCamera = () => {\r\n if (this._spectatorCamera) {\r\n this._spectatorCamera.position.copyFrom(this.camera.rigCameras[0].globalPosition);\r\n this._spectatorCamera.rotationQuaternion.copyFrom(this.camera.rigCameras[0].absoluteRotation);\r\n }\r\n };\r\n const onStateChanged = () => {\r\n if (this.state === WebXRState.IN_XR) {\r\n this._spectatorCamera = new UniversalCamera('webxr-spectator', Vector3.Zero(), this.scene);\r\n this._spectatorCamera.rotationQuaternion = new Quaternion();\r\n this.scene.activeCameras = [this.camera, this._spectatorCamera];\r\n this.sessionManager.onXRFrameObservable.add(updateSpectatorCamera);\r\n this.scene.onAfterRenderCameraObservable.add((camera) => {\r\n if (camera === this.camera) {\r\n // reset the dimensions object for correct resizing\r\n this.scene.getEngine().framebufferDimensionsObject = null;\r\n }\r\n });\r\n } else if (this.state === WebXRState.EXITING_XR) {\r\n this.sessionManager.onXRFrameObservable.removeCallback(updateSpectatorCamera);\r\n this.scene.activeCameras = null;\r\n }\r\n };\r\n this._spectatorMode = true;\r\n this.onStateChangedObservable.add(onStateChanged);\r\n onStateChanged();\r\n }\r\n }\r\n\r\n private _nonXRToXRCamera() {\r\n this.camera.setTransformationFromNonVRCamera(this._nonVRCamera!);\r\n this.onInitialXRPoseSetObservable.notifyObservers(this.camera);\r\n }\r\n\r\n private _setState(val: WebXRState) {\r\n if (this.state === val) {\r\n return;\r\n }\r\n this.state = val;\r\n this.onStateChangedObservable.notifyObservers(this.state);\r\n }\r\n}\r\n"]}
@@ -18,9 +18,7 @@ var WebXRLayerRenderTargetTextureProvider = /** @class */ (function () {
18
18
  // Create render target texture from the internal texture
19
19
  var renderTargetTexture = new RenderTargetTexture("XR renderTargetTexture", { width: width, height: height }, this._scene);
20
20
  var renderTargetWrapper = renderTargetTexture.renderTarget;
21
- if (!!framebuffer) {
22
- renderTargetWrapper._framebuffer = framebuffer;
23
- }
21
+ renderTargetWrapper._framebuffer = framebuffer;
24
22
  // Create internal texture
25
23
  var internalTexture = new InternalTexture(engine, InternalTextureSource.Unknown, true);
26
24
  internalTexture.width = width;
@@ -1 +1 @@
1
- {"version":3,"file":"webXRRenderTargetTextureProvider.js","sourceRoot":"","sources":["../../../sourceES6/core/XR/webXRRenderTargetTextureProvider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAgChF;;;GAGG;AACH;IAQI,+CACqB,MAAa,EACd,YAA+B;QAD9B,WAAM,GAAN,MAAM,CAAO;QACd,iBAAY,GAAZ,YAAY,CAAmB;QALzC,0BAAqB,GAAG,IAAI,KAAK,EAAuB,CAAC;IAKZ,CAAC;IAE9C,0EAA0B,GAApC,UACI,KAAa,EACb,MAAc,EACd,WAAuC,EACvC,YAAmC,EACnC,mBAA0C;QAC1C,IAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE;YACT,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;SACzC;QAED,yDAAyD;QACzD,IAAM,mBAAmB,GAAG,IAAI,mBAAmB,CAAC,wBAAwB,EAAE,EAAE,KAAK,OAAA,EAAE,MAAM,QAAA,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9G,IAAM,mBAAmB,GAAG,mBAAmB,CAAC,YAAa,CAAC;QAC9D,IAAI,CAAC,CAAC,WAAW,EAAE;YACd,mBAAgD,CAAC,YAAY,GAAG,WAAW,CAAC;SAChF;QAED,0BAA0B;QAC1B,IAAM,eAAe,GAAG,IAAI,eAAe,CAAC,MAAM,EAAE,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACzF,eAAe,CAAC,KAAK,GAAG,KAAK,CAAC;QAC9B,eAAe,CAAC,MAAM,GAAG,MAAM,CAAC;QAChC,IAAI,CAAC,CAAC,YAAY,EAAE;YAChB,eAAe,CAAC,gBAAgB,GAAG,YAAY,CAAC;SACnD;QACD,mBAAmB,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;QACnD,mBAAmB,CAAC,QAAQ,GAAG,eAAe,CAAC;QAE/C,IAAI,CAAC,CAAC,mBAAmB,EAAE;YACvB,IAAM,iBAAiB,GAAG,IAAI,eAAe,CAAC,MAAM,EAAE,qBAAqB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;YAChG,iBAAiB,CAAC,KAAK,GAAG,KAAK,CAAC;YAChC,iBAAiB,CAAC,MAAM,GAAG,MAAM,CAAC;YAClC,iBAAiB,CAAC,gBAAgB,GAAG,mBAAmB,CAAC;YACzD,mBAAmB,CAAC,oBAAoB,GAAG,iBAAiB,CAAC;SAChE;QAED,mBAAmB,CAAC,gBAAgB,EAAE,CAAC;QACvC,gHAAgH;QAChH,IAAI,OAAO,cAAc,KAAK,WAAW,EAAE;YACvC,4BAA4B;YAC5B,mBAAmB,CAAC,gBAAgB,GAAG,IAAI,CAAC;SAC/C;QAED,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAErD,OAAO,mBAAmB,CAAC;IAC/B,CAAC;IAES,2EAA2B,GAArC,UAAsC,mBAAwC;QAC1E,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9F,mBAAmB,CAAC,OAAO,EAAE,CAAC;IAClC,CAAC;IAEM,wEAAwB,GAA/B;QACI,OAAO,IAAI,CAAC,sBAAsB,CAAC;IACvC,CAAC;IAEM,uDAAO,GAAd;QACI,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,UAAC,GAAG,IAAK,OAAA,GAAG,CAAC,OAAO,EAAE,EAAb,CAAa,CAAC,CAAC;QAC3D,IAAI,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1C,CAAC;IACL,4CAAC;AAAD,CAAC,AAzED,IAyEC","sourcesContent":["import { WebGLHardwareTexture } from \"../Engines/WebGL/webGLHardwareTexture\";\r\nimport { WebGLRenderTargetWrapper } from \"../Engines/WebGL/webGLRenderTargetWrapper\";\r\nimport { InternalTexture, InternalTextureSource } from \"../Materials/Textures/internalTexture\";\r\nimport { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture\";\r\nimport { Viewport } from \"../Maths/math.viewport\";\r\nimport { IDisposable, Scene } from \"../scene\";\r\nimport { Nullable } from \"../types\";\r\nimport { WebXRLayerWrapper } from \"./webXRLayerWrapper\";\r\n\r\n/**\r\n * An interface for objects that provide render target textures for XR rendering.\r\n */\r\nexport interface IWebXRRenderTargetTextureProvider extends IDisposable {\r\n /**\r\n * Attempts to set the framebuffer-size-normalized viewport to be rendered this frame for this view.\r\n * In the event of a failure, the supplied viewport is not updated.\r\n * @param viewport the viewport to which the view will be rendered\r\n * @param view the view for which to set the viewport\r\n * @returns whether the operation was successful\r\n */\r\n trySetViewportForView(viewport: Viewport, view: XRView): boolean;\r\n /**\r\n * Gets the correct render target texture to be rendered this frame for this eye\r\n * @param eye the eye for which to get the render target\r\n * @returns the render target for the specified eye or null if not available\r\n */\r\n getRenderTargetTextureForEye(eye: XREye): Nullable<RenderTargetTexture>;\r\n /**\r\n * Gets the correct render target texture to be rendered this frame for this view\r\n * @param view the view for which to get the render target\r\n * @returns the render target for the specified view or null if not available\r\n */\r\n getRenderTargetTextureForView(view: XRView): Nullable<RenderTargetTexture>;\r\n}\r\n\r\n/**\r\n * Provides render target textures and other important rendering information for a given XRLayer.\r\n * @hidden\r\n */\r\nexport abstract class WebXRLayerRenderTargetTextureProvider implements IWebXRRenderTargetTextureProvider {\r\n public abstract trySetViewportForView(viewport: Viewport, view: XRView): boolean;\r\n public abstract getRenderTargetTextureForEye(eye: XREye): Nullable<RenderTargetTexture>;\r\n public abstract getRenderTargetTextureForView(view: XRView): Nullable<RenderTargetTexture>;\r\n\r\n protected _renderTargetTextures = new Array<RenderTargetTexture>();\r\n protected _framebufferDimensions: Nullable<{ framebufferWidth: number, framebufferHeight: number }>;\r\n\r\n constructor(\r\n private readonly _scene: Scene,\r\n public readonly layerWrapper: WebXRLayerWrapper) { }\r\n\r\n protected _createRenderTargetTexture(\r\n width: number,\r\n height: number,\r\n framebuffer: Nullable<WebGLFramebuffer>,\r\n colorTexture?: WebGLHardwareTexture,\r\n depthStencilTexture?: WebGLHardwareTexture): RenderTargetTexture {\r\n const engine = this._scene.getEngine();\r\n if (!engine) {\r\n throw new Error(\"Engine is disposed\");\r\n }\r\n\r\n // Create render target texture from the internal texture\r\n const renderTargetTexture = new RenderTargetTexture(\"XR renderTargetTexture\", { width, height }, this._scene);\r\n const renderTargetWrapper = renderTargetTexture.renderTarget!;\r\n if (!!framebuffer) {\r\n (renderTargetWrapper as WebGLRenderTargetWrapper)._framebuffer = framebuffer;\r\n }\r\n\r\n // Create internal texture\r\n const internalTexture = new InternalTexture(engine, InternalTextureSource.Unknown, true);\r\n internalTexture.width = width;\r\n internalTexture.height = height;\r\n if (!!colorTexture) {\r\n internalTexture._hardwareTexture = colorTexture;\r\n }\r\n renderTargetWrapper.setTexture(internalTexture, 0);\r\n renderTargetTexture._texture = internalTexture;\r\n\r\n if (!!depthStencilTexture) {\r\n const internalDSTexture = new InternalTexture(engine, InternalTextureSource.DepthStencil, true);\r\n internalDSTexture.width = width;\r\n internalDSTexture.height = height;\r\n internalDSTexture._hardwareTexture = depthStencilTexture;\r\n renderTargetWrapper._depthStencilTexture = internalDSTexture;\r\n }\r\n\r\n renderTargetTexture.disableRescaling();\r\n // Firefox reality fails if skipInitialClear is set to true, so make sure only modern XR implementations set it.\r\n if (typeof XRWebGLBinding !== \"undefined\") {\r\n // WebXR pre-clears textures\r\n renderTargetTexture.skipInitialClear = true;\r\n }\r\n\r\n this._renderTargetTextures.push(renderTargetTexture);\r\n\r\n return renderTargetTexture;\r\n }\r\n\r\n protected _destroyRenderTargetTexture(renderTargetTexture: RenderTargetTexture) {\r\n this._renderTargetTextures.splice(this._renderTargetTextures.indexOf(renderTargetTexture), 1);\r\n renderTargetTexture.dispose();\r\n }\r\n\r\n public getFramebufferDimensions(): Nullable<{ framebufferWidth: number, framebufferHeight: number }> {\r\n return this._framebufferDimensions;\r\n }\r\n\r\n public dispose() {\r\n this._renderTargetTextures.forEach((rtt) => rtt.dispose());\r\n this._renderTargetTextures.length = 0;\r\n }\r\n}"]}
1
+ {"version":3,"file":"webXRRenderTargetTextureProvider.js","sourceRoot":"","sources":["../../../sourceES6/core/XR/webXRRenderTargetTextureProvider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAgChF;;;GAGG;AACH;IAQI,+CACqB,MAAa,EACd,YAA+B;QAD9B,WAAM,GAAN,MAAM,CAAO;QACd,iBAAY,GAAZ,YAAY,CAAmB;QALzC,0BAAqB,GAAG,IAAI,KAAK,EAAuB,CAAC;IAKZ,CAAC;IAE9C,0EAA0B,GAApC,UACI,KAAa,EACb,MAAc,EACd,WAAuC,EACvC,YAAmC,EACnC,mBAA0C;QAC1C,IAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE;YACT,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;SACzC;QAED,yDAAyD;QACzD,IAAM,mBAAmB,GAAG,IAAI,mBAAmB,CAAC,wBAAwB,EAAE,EAAE,KAAK,OAAA,EAAE,MAAM,QAAA,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9G,IAAM,mBAAmB,GAAG,mBAAmB,CAAC,YAAa,CAAC;QAC7D,mBAAgD,CAAC,YAAY,GAAG,WAAW,CAAC;QAE7E,0BAA0B;QAC1B,IAAM,eAAe,GAAG,IAAI,eAAe,CAAC,MAAM,EAAE,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACzF,eAAe,CAAC,KAAK,GAAG,KAAK,CAAC;QAC9B,eAAe,CAAC,MAAM,GAAG,MAAM,CAAC;QAChC,IAAI,CAAC,CAAC,YAAY,EAAE;YAChB,eAAe,CAAC,gBAAgB,GAAG,YAAY,CAAC;SACnD;QACD,mBAAmB,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;QACnD,mBAAmB,CAAC,QAAQ,GAAG,eAAe,CAAC;QAE/C,IAAI,CAAC,CAAC,mBAAmB,EAAE;YACvB,IAAM,iBAAiB,GAAG,IAAI,eAAe,CAAC,MAAM,EAAE,qBAAqB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;YAChG,iBAAiB,CAAC,KAAK,GAAG,KAAK,CAAC;YAChC,iBAAiB,CAAC,MAAM,GAAG,MAAM,CAAC;YAClC,iBAAiB,CAAC,gBAAgB,GAAG,mBAAmB,CAAC;YACzD,mBAAmB,CAAC,oBAAoB,GAAG,iBAAiB,CAAC;SAChE;QAED,mBAAmB,CAAC,gBAAgB,EAAE,CAAC;QACvC,gHAAgH;QAChH,IAAI,OAAO,cAAc,KAAK,WAAW,EAAE;YACvC,4BAA4B;YAC5B,mBAAmB,CAAC,gBAAgB,GAAG,IAAI,CAAC;SAC/C;QAED,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAErD,OAAO,mBAAmB,CAAC;IAC/B,CAAC;IAES,2EAA2B,GAArC,UAAsC,mBAAwC;QAC1E,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9F,mBAAmB,CAAC,OAAO,EAAE,CAAC;IAClC,CAAC;IAEM,wEAAwB,GAA/B;QACI,OAAO,IAAI,CAAC,sBAAsB,CAAC;IACvC,CAAC;IAEM,uDAAO,GAAd;QACI,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,UAAC,GAAG,IAAK,OAAA,GAAG,CAAC,OAAO,EAAE,EAAb,CAAa,CAAC,CAAC;QAC3D,IAAI,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1C,CAAC;IACL,4CAAC;AAAD,CAAC,AAvED,IAuEC","sourcesContent":["import { WebGLHardwareTexture } from \"../Engines/WebGL/webGLHardwareTexture\";\r\nimport { WebGLRenderTargetWrapper } from \"../Engines/WebGL/webGLRenderTargetWrapper\";\r\nimport { InternalTexture, InternalTextureSource } from \"../Materials/Textures/internalTexture\";\r\nimport { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture\";\r\nimport { Viewport } from \"../Maths/math.viewport\";\r\nimport { IDisposable, Scene } from \"../scene\";\r\nimport { Nullable } from \"../types\";\r\nimport { WebXRLayerWrapper } from \"./webXRLayerWrapper\";\r\n\r\n/**\r\n * An interface for objects that provide render target textures for XR rendering.\r\n */\r\nexport interface IWebXRRenderTargetTextureProvider extends IDisposable {\r\n /**\r\n * Attempts to set the framebuffer-size-normalized viewport to be rendered this frame for this view.\r\n * In the event of a failure, the supplied viewport is not updated.\r\n * @param viewport the viewport to which the view will be rendered\r\n * @param view the view for which to set the viewport\r\n * @returns whether the operation was successful\r\n */\r\n trySetViewportForView(viewport: Viewport, view: XRView): boolean;\r\n /**\r\n * Gets the correct render target texture to be rendered this frame for this eye\r\n * @param eye the eye for which to get the render target\r\n * @returns the render target for the specified eye or null if not available\r\n */\r\n getRenderTargetTextureForEye(eye: XREye): Nullable<RenderTargetTexture>;\r\n /**\r\n * Gets the correct render target texture to be rendered this frame for this view\r\n * @param view the view for which to get the render target\r\n * @returns the render target for the specified view or null if not available\r\n */\r\n getRenderTargetTextureForView(view: XRView): Nullable<RenderTargetTexture>;\r\n}\r\n\r\n/**\r\n * Provides render target textures and other important rendering information for a given XRLayer.\r\n * @hidden\r\n */\r\nexport abstract class WebXRLayerRenderTargetTextureProvider implements IWebXRRenderTargetTextureProvider {\r\n public abstract trySetViewportForView(viewport: Viewport, view: XRView): boolean;\r\n public abstract getRenderTargetTextureForEye(eye: XREye): Nullable<RenderTargetTexture>;\r\n public abstract getRenderTargetTextureForView(view: XRView): Nullable<RenderTargetTexture>;\r\n\r\n protected _renderTargetTextures = new Array<RenderTargetTexture>();\r\n protected _framebufferDimensions: Nullable<{ framebufferWidth: number, framebufferHeight: number }>;\r\n\r\n constructor(\r\n private readonly _scene: Scene,\r\n public readonly layerWrapper: WebXRLayerWrapper) { }\r\n\r\n protected _createRenderTargetTexture(\r\n width: number,\r\n height: number,\r\n framebuffer: Nullable<WebGLFramebuffer>,\r\n colorTexture?: WebGLHardwareTexture,\r\n depthStencilTexture?: WebGLHardwareTexture): RenderTargetTexture {\r\n const engine = this._scene.getEngine();\r\n if (!engine) {\r\n throw new Error(\"Engine is disposed\");\r\n }\r\n\r\n // Create render target texture from the internal texture\r\n const renderTargetTexture = new RenderTargetTexture(\"XR renderTargetTexture\", { width, height }, this._scene);\r\n const renderTargetWrapper = renderTargetTexture.renderTarget!;\r\n (renderTargetWrapper as WebGLRenderTargetWrapper)._framebuffer = framebuffer;\r\n\r\n // Create internal texture\r\n const internalTexture = new InternalTexture(engine, InternalTextureSource.Unknown, true);\r\n internalTexture.width = width;\r\n internalTexture.height = height;\r\n if (!!colorTexture) {\r\n internalTexture._hardwareTexture = colorTexture;\r\n }\r\n renderTargetWrapper.setTexture(internalTexture, 0);\r\n renderTargetTexture._texture = internalTexture;\r\n\r\n if (!!depthStencilTexture) {\r\n const internalDSTexture = new InternalTexture(engine, InternalTextureSource.DepthStencil, true);\r\n internalDSTexture.width = width;\r\n internalDSTexture.height = height;\r\n internalDSTexture._hardwareTexture = depthStencilTexture;\r\n renderTargetWrapper._depthStencilTexture = internalDSTexture;\r\n }\r\n\r\n renderTargetTexture.disableRescaling();\r\n // Firefox reality fails if skipInitialClear is set to true, so make sure only modern XR implementations set it.\r\n if (typeof XRWebGLBinding !== \"undefined\") {\r\n // WebXR pre-clears textures\r\n renderTargetTexture.skipInitialClear = true;\r\n }\r\n\r\n this._renderTargetTextures.push(renderTargetTexture);\r\n\r\n return renderTargetTexture;\r\n }\r\n\r\n protected _destroyRenderTargetTexture(renderTargetTexture: RenderTargetTexture) {\r\n this._renderTargetTextures.splice(this._renderTargetTextures.indexOf(renderTargetTexture), 1);\r\n renderTargetTexture.dispose();\r\n }\r\n\r\n public getFramebufferDimensions(): Nullable<{ framebufferWidth: number, framebufferHeight: number }> {\r\n return this._framebufferDimensions;\r\n }\r\n\r\n public dispose() {\r\n this._renderTargetTextures.forEach((rtt) => rtt.dispose());\r\n this._renderTargetTextures.length = 0;\r\n }\r\n}"]}
@@ -18,7 +18,6 @@ export declare class WebXRSessionManager implements IDisposable, IWebXRRenderTar
18
18
  private _referenceSpace;
19
19
  private _baseLayerWrapper;
20
20
  private _baseLayerRTTProvider;
21
- private _sessionEnded;
22
21
  private _xrNavigator;
23
22
  private _sessionMode;
24
23
  /**
@@ -62,6 +61,14 @@ export declare class WebXRSessionManager implements IDisposable, IWebXRRenderTar
62
61
  * or get the offset the player is currently at.
63
62
  */
64
63
  viewerReferenceSpace: XRReferenceSpace;
64
+ /**
65
+ * Are we currently in the XR loop?
66
+ */
67
+ inXRFrameLoop: boolean;
68
+ /**
69
+ * Are we in an XR session?
70
+ */
71
+ inXRSession: boolean;
65
72
  /**
66
73
  * Constructs a WebXRSessionManager, this must be initialized within a user action before usage
67
74
  * @param scene The scene which the session should be created for
@@ -191,6 +198,12 @@ export declare class WebXRSessionManager implements IDisposable, IWebXRRenderTar
191
198
  * @returns a promise that resolves once the framerate has been set
192
199
  */
193
200
  updateTargetFrameRate(rate: number): Promise<void>;
201
+ /**
202
+ * Run a callback in the xr render loop
203
+ * @param callback the callback to call when in XR Frame
204
+ * @param ignoreIfNotInSession if no session is currently running, run it first thing on the next session
205
+ */
206
+ runInXRFrame(callback: () => void, ignoreIfNotInSession?: boolean): void;
194
207
  /**
195
208
  * Check if fixed foveation is supported on this device
196
209
  */
@@ -17,7 +17,6 @@ var WebXRSessionManager = /** @class */ (function () {
17
17
  scene) {
18
18
  var _this = this;
19
19
  this.scene = scene;
20
- this._sessionEnded = false;
21
20
  /** WebXR timestamp updated every frame */
22
21
  this.currentTimestamp = -1;
23
22
  /**
@@ -41,6 +40,14 @@ var WebXRSessionManager = /** @class */ (function () {
41
40
  * Fires when the xr session is initialized: right after requestSession was called and returned with a successful result
42
41
  */
43
42
  this.onXRSessionInit = new Observable();
43
+ /**
44
+ * Are we currently in the XR loop?
45
+ */
46
+ this.inXRFrameLoop = false;
47
+ /**
48
+ * Are we in an XR session?
49
+ */
50
+ this.inXRSession = false;
44
51
  this._engine = scene.getEngine();
45
52
  this._engine.onDisposeObservable.addOnce(function () {
46
53
  _this._engine = null;
@@ -80,7 +87,7 @@ var WebXRSessionManager = /** @class */ (function () {
80
87
  */
81
88
  WebXRSessionManager.prototype.dispose = function () {
82
89
  // disposing without leaving XR? Exit XR first
83
- if (!this._sessionEnded) {
90
+ if (this.inXRSession) {
84
91
  this.exitXRAsync();
85
92
  }
86
93
  this.onXRFrameObservable.clear();
@@ -93,8 +100,8 @@ var WebXRSessionManager = /** @class */ (function () {
93
100
  * @returns Promise which resolves after it exits XR
94
101
  */
95
102
  WebXRSessionManager.prototype.exitXRAsync = function () {
96
- if (this.session && !this._sessionEnded) {
97
- this._sessionEnded = true;
103
+ if (this.session && !this.inXRSession) {
104
+ this.inXRSession = false;
98
105
  return this.session.end().catch(function (e) {
99
106
  Logger.Warn("Could not end XR session.");
100
107
  });
@@ -174,11 +181,11 @@ var WebXRSessionManager = /** @class */ (function () {
174
181
  _this.session = session;
175
182
  _this._sessionMode = xrSessionMode;
176
183
  _this.onXRSessionInit.notifyObservers(session);
177
- _this._sessionEnded = false;
184
+ _this.inXRSession = true;
178
185
  // handle when the session is ended (By calling session.end or device ends its own session eg. pressing home button on phone)
179
186
  _this.session.addEventListener("end", function () {
180
187
  var _a;
181
- _this._sessionEnded = true;
188
+ _this.inXRSession = false;
182
189
  // Notify frame observers
183
190
  _this.onXRSessionEnded.notifyObservers(null);
184
191
  if (_this._engine) {
@@ -221,7 +228,7 @@ var WebXRSessionManager = /** @class */ (function () {
221
228
  WebXRSessionManager.prototype.runXRRenderLoop = function () {
222
229
  var _this = this;
223
230
  var _a;
224
- if (this._sessionEnded || !this._engine) {
231
+ if (!this.inXRSession || !this._engine) {
225
232
  return;
226
233
  }
227
234
  // Tell the engine's render loop to be driven by the xr session's refresh rate and provide xr pose information
@@ -229,17 +236,19 @@ var WebXRSessionManager = /** @class */ (function () {
229
236
  requestAnimationFrame: this.session.requestAnimationFrame.bind(this.session),
230
237
  renderFunction: function (timestamp, xrFrame) {
231
238
  var _a;
232
- if (_this._sessionEnded || !_this._engine) {
239
+ if (!_this.inXRSession || !_this._engine) {
233
240
  return;
234
241
  }
235
242
  // Store the XR frame and timestamp in the session manager
236
243
  _this.currentFrame = xrFrame;
237
244
  _this.currentTimestamp = timestamp;
238
245
  if (xrFrame) {
246
+ _this.inXRFrameLoop = true;
239
247
  _this._engine.framebufferDimensionsObject = ((_a = _this._baseLayerRTTProvider) === null || _a === void 0 ? void 0 : _a.getFramebufferDimensions()) || null;
240
248
  _this.onXRFrameObservable.notifyObservers(xrFrame);
241
249
  _this._engine._renderLoop();
242
250
  _this._engine.framebufferDimensionsObject = null;
251
+ _this.inXRFrameLoop = false;
243
252
  }
244
253
  },
245
254
  };
@@ -386,6 +395,20 @@ var WebXRSessionManager = /** @class */ (function () {
386
395
  WebXRSessionManager.prototype.updateTargetFrameRate = function (rate) {
387
396
  return this.session.updateTargetFrameRate(rate);
388
397
  };
398
+ /**
399
+ * Run a callback in the xr render loop
400
+ * @param callback the callback to call when in XR Frame
401
+ * @param ignoreIfNotInSession if no session is currently running, run it first thing on the next session
402
+ */
403
+ WebXRSessionManager.prototype.runInXRFrame = function (callback, ignoreIfNotInSession) {
404
+ if (ignoreIfNotInSession === void 0) { ignoreIfNotInSession = true; }
405
+ if (this.inXRFrameLoop) {
406
+ callback();
407
+ }
408
+ else if (this.inXRSession || !ignoreIfNotInSession) {
409
+ this.onXRFrameObservable.addOnce(callback);
410
+ }
411
+ };
389
412
  Object.defineProperty(WebXRSessionManager.prototype, "isFixedFoveationSupported", {
390
413
  /**
391
414
  * Check if fixed foveation is supported on this device