@onerjs/core 8.44.8 → 8.45.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.
- package/Engines/WebGPU/webgpuShaderProcessingContext.d.ts +1 -0
- package/Engines/WebGPU/webgpuShaderProcessingContext.js.map +1 -1
- package/Engines/WebGPU/webgpuShaderProcessor.d.ts +1 -1
- package/Engines/WebGPU/webgpuShaderProcessor.js +2 -2
- package/Engines/WebGPU/webgpuShaderProcessor.js.map +1 -1
- package/Engines/WebGPU/webgpuShaderProcessorsWGSL.js +20 -2
- package/Engines/WebGPU/webgpuShaderProcessorsWGSL.js.map +1 -1
- package/Engines/engine.d.ts +25 -0
- package/Engines/engineCapabilities.d.ts +2 -0
- package/Engines/engineCapabilities.js.map +1 -1
- package/Engines/nullEngine.js +1 -0
- package/Engines/nullEngine.js.map +1 -1
- package/Engines/thinEngine.js +3 -0
- package/Engines/thinEngine.js.map +1 -1
- package/Engines/thinNativeEngine.js +1 -0
- package/Engines/thinNativeEngine.js.map +1 -1
- package/Engines/webgpuEngine.js +1 -0
- package/Engines/webgpuEngine.js.map +1 -1
- package/Gizmos/boundingBoxGizmo.d.ts +2 -0
- package/Gizmos/boundingBoxGizmo.js +56 -7
- package/Gizmos/boundingBoxGizmo.js.map +1 -1
- package/Layers/thinEffectLayer.js +1 -2
- package/Layers/thinEffectLayer.js.map +1 -1
- package/Materials/Textures/renderTargetTexture.d.ts +2 -2
- package/Materials/Textures/renderTargetTexture.js +2 -2
- package/Materials/Textures/renderTargetTexture.js.map +1 -1
- package/Misc/stringTools.js +20 -14
- package/Misc/stringTools.js.map +1 -1
- package/Misc/thinMinMaxReducer.js +4 -3
- package/Misc/thinMinMaxReducer.js.map +1 -1
- package/PostProcesses/thinAnaglyphPostProcess.js +2 -2
- package/PostProcesses/thinAnaglyphPostProcess.js.map +1 -1
- package/PostProcesses/thinBlackAndWhitePostProcess.js +2 -2
- package/PostProcesses/thinBlackAndWhitePostProcess.js.map +1 -1
- package/PostProcesses/thinBloomMergePostProcess.js +2 -2
- package/PostProcesses/thinBloomMergePostProcess.js.map +1 -1
- package/PostProcesses/thinBlurPostProcess.js +2 -2
- package/PostProcesses/thinBlurPostProcess.js.map +1 -1
- package/PostProcesses/thinChromaticAberrationPostProcess.js +2 -2
- package/PostProcesses/thinChromaticAberrationPostProcess.js.map +1 -1
- package/PostProcesses/thinCircleOfConfusionPostProcess.js +2 -2
- package/PostProcesses/thinCircleOfConfusionPostProcess.js.map +1 -1
- package/PostProcesses/thinConvolutionPostProcess.js +2 -2
- package/PostProcesses/thinConvolutionPostProcess.js.map +1 -1
- package/PostProcesses/thinCustomPostProcess.js +2 -2
- package/PostProcesses/thinCustomPostProcess.js.map +1 -1
- package/PostProcesses/thinDepthOfFieldMergePostProcess.js +2 -2
- package/PostProcesses/thinDepthOfFieldMergePostProcess.js.map +1 -1
- package/PostProcesses/thinExtractHighlightsPostProcess.js +2 -2
- package/PostProcesses/thinExtractHighlightsPostProcess.js.map +1 -1
- package/PostProcesses/thinFXAAPostProcess.js +2 -2
- package/PostProcesses/thinFXAAPostProcess.js.map +1 -1
- package/PostProcesses/thinFilterPostProcess.js +2 -2
- package/PostProcesses/thinFilterPostProcess.js.map +1 -1
- package/PostProcesses/thinGrainPostProcess.js +2 -2
- package/PostProcesses/thinGrainPostProcess.js.map +1 -1
- package/PostProcesses/thinImageProcessingPostProcess.js +1 -2
- package/PostProcesses/thinImageProcessingPostProcess.js.map +1 -1
- package/PostProcesses/thinPassPostProcess.js +4 -4
- package/PostProcesses/thinPassPostProcess.js.map +1 -1
- package/PostProcesses/thinSSAO2BlurPostProcess.js +2 -2
- package/PostProcesses/thinSSAO2BlurPostProcess.js.map +1 -1
- package/PostProcesses/thinSSAO2CombinePostProcess.js +2 -2
- package/PostProcesses/thinSSAO2CombinePostProcess.js.map +1 -1
- package/PostProcesses/thinSSRBlurCombinerPostProcess.js +2 -2
- package/PostProcesses/thinSSRBlurCombinerPostProcess.js.map +1 -1
- package/PostProcesses/thinSSRBlurPostProcess.js +2 -2
- package/PostProcesses/thinSSRBlurPostProcess.js.map +1 -1
- package/PostProcesses/thinScreenSpaceCurvaturePostProcess.js +2 -2
- package/PostProcesses/thinScreenSpaceCurvaturePostProcess.js.map +1 -1
- package/PostProcesses/thinSharpenPostProcess.js +2 -2
- package/PostProcesses/thinSharpenPostProcess.js.map +1 -1
- package/PostProcesses/thinTonemapPostProcess.js +2 -2
- package/PostProcesses/thinTonemapPostProcess.js.map +1 -1
- package/Rendering/IBLShadows/iblShadowsRenderPipeline.js +2 -3
- package/Rendering/IBLShadows/iblShadowsRenderPipeline.js.map +1 -1
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js +1 -2
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js.map +1 -1
- package/Rendering/iblCdfGenerator.js +1 -2
- package/Rendering/iblCdfGenerator.js.map +1 -1
- package/Rendering/objectRenderer.d.ts +8 -2
- package/Rendering/objectRenderer.js +8 -2
- package/Rendering/objectRenderer.js.map +1 -1
- package/XR/features/WebXRControllerPointerSelection.d.ts +25 -0
- package/XR/features/WebXRControllerPointerSelection.js +76 -0
- package/XR/features/WebXRControllerPointerSelection.js.map +1 -1
- package/XR/features/WebXRControllerTeleportation.d.ts +13 -0
- package/XR/features/WebXRControllerTeleportation.js +38 -11
- package/XR/features/WebXRControllerTeleportation.js.map +1 -1
- package/package.json +1 -1
- package/scene.js +6 -0
- package/scene.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebXRControllerPointerSelection.js","sourceRoot":"","sources":["../../../../../dev/core/src/XR/features/WebXRControllerPointerSelection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AASjF,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAI5E,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AA+GzC;;GAEG;AACH,MAAM,OAAO,+BAAgC,SAAQ,oBAAoB;IA4HrE;;;;OAIG;IACH,YACI,iBAAsC,EACrB,QAAiD;QAElE,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAFR,aAAQ,GAAR,QAAQ,CAAyC;QAhI9D,sBAAiB,GAAG,CAAC,YAA8B,EAAE,EAAE;YAC3D,IAAI,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC3C,mBAAmB;gBACnB,OAAO;YACX,CAAC;YAED,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,oBAAoB,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAEtK,qBAAqB;YACrB,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG;gBACvC,YAAY;gBACZ,YAAY;gBACZ,aAAa;gBACb,gBAAgB,EAAE,IAAI;gBACtB,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,IAAI,GAAG,CAAC,IAAI,OAAO,EAAE,EAAE,IAAI,OAAO,EAAE,CAAC;gBAC7C,yBAAyB,EAAE,KAAK;gBAChC,EAAE,EAAE,+BAA+B,CAAC,UAAU,EAAE;aACnD,CAAC;YAEF,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3B,IACI,CAAC,IAAI,CAAC,QAAQ,CAAC,sCAAsC;oBACrD,IAAI,CAAC,QAAQ,CAAC,mBAAmB;oBACjC,YAAY,CAAC,WAAW,CAAC,UAAU,KAAK,IAAI,CAAC,QAAQ,CAAC,mBAAmB,EAC3E,CAAC;oBACC,IAAI,CAAC,mBAAmB,GAAG,YAAY,CAAC,QAAQ,CAAC;gBACrD,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,sCAAsC,EAAE,CAAC;oBACxD,IAAI,CAAC,mBAAmB,GAAG,YAAY,CAAC,QAAQ,CAAC;gBACrD,CAAC;YACL,CAAC;YAED,QAAQ,YAAY,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC;gBAC7C,KAAK,iBAAiB;oBAClB,OAAO,IAAI,CAAC,4BAA4B,CAAC,YAAY,CAAC,CAAC;gBAC3D,KAAK,MAAM;oBACP,OAAO,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;gBAC9C,KAAK,QAAQ,CAAC;gBACd,KAAK,mBAAmB;oBACpB,OAAO,IAAI,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC;YACvD,CAAC;QACL,CAAC,CAAC;QAEM,iBAAY,GAoBhB,EAAE,CAAC;QAEC,6BAAwB,GAAG,IAAI,OAAO,EAAE,CAAC;QAejD;;WAEG;QACI,2BAAsB,GAAY,IAAI,CAAC;QAC9C;;WAEG;QACI,iCAA4B,GAAY,IAAI,CAAC;QACpD;;WAEG;QACI,wBAAmB,GAAY,IAAI,CAAC;QAC3C;;WAEG;QACI,yBAAoB,GAAY,IAAI,CAAC;QAC5C;;WAEG;QACI,4BAAuB,GAAW,IAAI,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACnE;;WAEG;QACI,6BAAwB,GAAW,IAAI,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACpE;;WAEG;QACI,8BAAyB,GAAW,IAAI,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACrE;;WAEG;QACI,6BAAwB,GAAW,IAAI,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QA6J5D,oBAAe,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpC,0BAAqB,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QACvC,iBAAY,GAAG,IAAI,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QA7I5C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC;QAE3C,8EAA8E;QAC9E,qEAAqE;QACrE,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,aAAa,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3H,IAAI,CAAC,QAAQ,CAAC,eAAe,GAAG,IAAI,CAAC;QACzC,CAAC;QAED,yCAAyC;QACzC,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;YAChC,IAAI,CAAC,QAAQ,CAAC,sCAAsC,GAAG,IAAI,CAAC;YAC5D,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC;QACrC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACa,MAAM;QAClB,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAClB,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YACzD,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;QACvC,CAAC;QACD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,2BAA2B,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;QAC5G,IAAI,CAAC,qBAAqB,CACtB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,6BAA6B,EACnD,CAAC,UAAU,EAAE,EAAE;YACX,wBAAwB;YACxB,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAChD,CAAC,EACD,IAAI,CACP,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,gCAAgC,GAAG,IAAI,CAAC;QAEpD,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;YAE7C,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;YAE/E,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG;gBAC1B,WAAW;gBACX,YAAY;gBACZ,aAAa;gBACb,gBAAgB,EAAE,IAAI;gBACtB,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,IAAI,GAAG,CAAC,IAAI,OAAO,EAAE,EAAE,IAAI,OAAO,EAAE,CAAC;gBAC7C,yBAAyB,EAAE,KAAK;gBAChC,EAAE,EAAE,+BAA+B,CAAC,UAAU,EAAE;aACnD,CAAC;YACF,IAAI,CAAC,eAAe,EAAE,CAAC;QAC3B,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACa,MAAM;QAClB,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAClB,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5C,KAAK,MAAM,YAAY,IAAI,IAAI,EAAE,CAAC;YAC9B,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;QACzC,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACI,mBAAmB,CAAC,YAAoB;QAC3C,IAAI,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,gBAAgB,CAAC;QAC5D,CAAC;aAAM,CAAC;YACJ,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACI,0BAA0B,CAAC,EAAU;QACxC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAE5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBACvC,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC;YAC3D,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;OAEG;IACI,uCAAuC,CAAC,EAAU;QACrD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAE5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBACvC,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC;YAChE,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;OAEG;IACI,uCAAuC,CAAC,EAAU,EAAE,KAAc;QACrE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAE5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBACvC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,yBAAyB,GAAG,KAAK,CAAC;gBAC7D,OAAO;YACX,CAAC;QACL,CAAC;IACL,CAAC;IAMS,UAAU,CAAC,QAAiB;QAClC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5C,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;YACpB,qBAAqB;YACrB,wCAAwC;YACxC,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YAC7C,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,IAAI,cAAc,CAAC,YAAY,EAAE,WAAW,CAAC,aAAa,KAAK,mBAAmB,EAAE,CAAC;gBAClH,SAAS;YACb,CAAC;YACD,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,sCAAsC,IAAI,EAAE,KAAK,IAAI,CAAC,mBAAmB,CAAC,IAAI,cAAc,CAAC,yBAAyB,EAAE,CAAC;gBACzI,cAAc,CAAC,aAAa,CAAC,SAAS,GAAG,KAAK,CAAC;gBAC/C,cAAc,CAAC,YAAY,CAAC,SAAS,GAAG,KAAK,CAAC;gBAC9C,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC;gBAC3B,SAAS;YACb,CAAC;YAED,cAAc,CAAC,YAAY,CAAC,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC;YAEjE,IAAI,wBAAiC,CAAC;YAEtC,qCAAqC;YACrC,IAAI,cAAc,CAAC,YAAY,EAAE,CAAC;gBAC9B,wBAAwB;oBACpB,IAAI,CAAC,QAAQ,CAAC,oBAAoB,IAAI,cAAc,CAAC,YAAY,CAAC,IAAI;wBAClE,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ;wBAC3C,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACvD,cAAc,CAAC,YAAY,CAAC,uBAAuB,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;YACnH,CAAC;iBAAM,IAAI,cAAc,CAAC,WAAW,EAAE,CAAC;gBACpC,wBAAwB,GAAG,cAAc,CAAC,WAAW,CAAC,QAAQ,CAAC;gBAC/D,cAAc,CAAC,WAAW,CAAC,kBAAkB,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YACzE,CAAC;iBAAM,CAAC;gBACJ,SAAS;YACb,CAAC;YAED,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC;gBACnC,cAAc,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YACpE,CAAC;YACD,8EAA8E;YAC9E,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,+BAA+B,IAAI,wBAAwB,EAAE,CAAC;gBAC7E,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC;gBAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC;gBAC9C,IAAI,MAAM,EAAE,CAAC;oBACT,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,cAAc,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,eAAe,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;oBACrJ,OAAO,CAAC,YAAY,CAAC,wBAAwB,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,uBAAuB,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;oBACtJ,YAAY;oBACZ,IACI,OAAO,IAAI,CAAC,qBAAqB,CAAC,CAAC,KAAK,QAAQ;wBAChD,OAAO,IAAI,CAAC,qBAAqB,CAAC,CAAC,KAAK,QAAQ;wBAChD,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;wBACpC,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;wBACpC,IAAI,CAAC,qBAAqB,CAAC,CAAC,KAAK,QAAQ;wBACzC,IAAI,CAAC,qBAAqB,CAAC,CAAC,KAAK,QAAQ,EAC3C,CAAC;wBACC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;wBAC9C,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;wBAE9C,cAAc,CAAC,iBAAiB,GAAG;4BAC/B,CAAC,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;4BAC/B,CAAC,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;yBAClC,CAAC;oBACN,CAAC;gBACL,CAAC;YACL,CAAC;YAED,IAAI,gBAAgB,GAAG,IAAI,CAAC;YAC5B,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC1B,gBAAgB,GAAG,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,kBAAkB,CAAC,oBAAoB,IAAI,IAAI,CAAC,qBAAqB,CAAC,CAAC;YAC9J,CAAC;YAED,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,oBAAoB,IAAI,IAAI,CAAC,qBAAqB,CAAC,CAAC;YACzI,IAAI,CAAC,gBAAgB,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,CAAC;gBAC7C,0BAA0B;gBAC1B,cAAc,CAAC,IAAI,GAAG,iBAAiB,CAAC;YAC5C,CAAC;iBAAM,IAAI,CAAC,iBAAiB,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,CAAC;gBACtD,2BAA2B;gBAC3B,cAAc,CAAC,IAAI,GAAG,gBAAgB,CAAC;YAC3C,CAAC;iBAAM,IAAI,gBAAgB,CAAC,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,EAAE,CAAC;gBAChE,iCAAiC;gBACjC,cAAc,CAAC,IAAI,GAAG,gBAAgB,CAAC;YAC3C,CAAC;iBAAM,CAAC;gBACJ,kCAAkC;gBAClC,cAAc,CAAC,IAAI,GAAG,iBAAiB,CAAC;YAC5C,CAAC;YAED,IAAI,cAAc,CAAC,IAAI,IAAI,cAAc,CAAC,YAAY,EAAE,CAAC;gBACrD,cAAc,CAAC,IAAI,CAAC,YAAY,GAAG,cAAc,CAAC,YAAY,CAAC,OAAO,CAAC;gBACvE,cAAc,CAAC,IAAI,CAAC,aAAa,GAAG,cAAc,CAAC,YAAY,CAAC,IAAI,IAAI,IAAI,CAAC;gBAC7E,cAAc,CAAC,IAAI,CAAC,UAAU,GAAG,cAAc,CAAC,YAAY,CAAC,OAAO,CAAC;gBACrE,cAAc,CAAC,MAAM,CAAC,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC;YAChE,CAAC;YAED,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC;YAEjC,IAAI,IAAI,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;gBACvC,qBAAqB;gBACrB,IAAI,CAAC,sBAAsB,CAAC,cAAc,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAExE,sBAAsB;gBACtB,cAAc,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACjE,cAAc,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAClE,cAAc,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAClE,cAAc,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAElE,sBAAsB;gBACtB,MAAM,UAAU,GAAG,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;gBACpG,MAAM,aAAa,GAAG,KAAK,CAAC;gBAC5B,cAAc,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACjE,IAAI,UAAU,EAAE,CAAC;oBACb,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;oBAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;oBAC/C,OAAO,CAAC,qBAAqB,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;oBAC/F,cAAc,CAAC,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;gBACtF,CAAC;gBACD,cAAc,CAAC,aAAa,CAAC,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC;gBACnE,cAAc,CAAC,gBAAgB,GAAG,IAAI,CAAC,UAAU,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACJ,cAAc,CAAC,aAAa,CAAC,SAAS,GAAG,KAAK,CAAC;gBAC/C,IAAI,CAAC,sBAAsB,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;gBAC5D,cAAc,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC3C,CAAC;QACL,CAAC;IACL,CAAC;IAED,IAAY,kBAAkB;QAC1B,OAAO,IAAI,CAAC,QAAQ,CAAC,uBAAuB,IAAI,oBAAoB,CAAC,mBAAmB,CAAC,iBAAiB,CAAC;IAC/G,CAAC;IAEO,eAAe,CAAC,YAA+B;QACnD,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,YAAY,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,CAAC;QAC9F,8CAA8C;QAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,IAAI,IAAI,CAAC;QACxD,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QAC9F,IAAI,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,WAAW,CACxB,WAAW,EACX;YACI,QAAQ,EAAE,MAAM,GAAG,EAAE;YACrB,SAAS,EAAE,MAAM,GAAG,CAAC;YACrB,YAAY,EAAE,EAAE;SACnB,EACD,eAAe,CAClB,CAAC;QACF,QAAQ,CAAC,SAAS,GAAG,KAAK,CAAC;QAC3B,QAAQ,CAAC,UAAU,GAAG,KAAK,CAAC;QAC5B,QAAQ,CAAC,MAAM,GAAG,cAAc,CAAC,aAAa,CAAC;QAC/C,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,aAAa,GAAG,KAAK,CAAC;QAC1B,MAAM,gBAAgB,GAAqB;YACvC,SAAS,EAAE,cAAc,CAAC,EAAE;YAC5B,WAAW,EAAE,IAAI;SACpB,CAAC;QACF,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,EAAE;YACjF,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;gBACvB,OAAO;YACX,CAAC;YACD,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,cAAc,CAAC,EAAE,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;YAChG,cAAc,CAAC,YAAY,CAAC,QAAS,CAAC,KAAK,GAAG,CAAC,CAAC;YAChD,QAAQ,CAAC,SAAS,GAAG,KAAK,CAAC;YAC3B,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC1B,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;oBACpD,IAAI,KAAK,GAAG,YAAY,GAAG,EAAE,EAAE,CAAC;wBAC5B,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC;oBAC9B,CAAC;oBAED,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,YAAY,EAAE,CAAC;oBAChD,IAAI,KAAK,IAAI,YAAY,EAAE,CAAC;wBACxB,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;wBACvE,yIAAyI;wBACzI,aAAa,GAAG,IAAI,CAAC;wBACrB,uDAAuD;wBACvD,IAAI,IAAI,CAAC,QAAQ,CAAC,0BAA0B,EAAE,CAAC;4BAC3C,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;wBACzE,CAAC;wBACD,QAAQ,CAAC,SAAS,GAAG,KAAK,CAAC;oBAC/B,CAAC;yBAAM,CAAC;wBACJ,MAAM,WAAW,GAAG,CAAC,GAAG,KAAK,GAAG,YAAY,CAAC;wBAC7C,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;oBAChE,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,IAAI,aAAa,EAAE,CAAC;wBAChB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,0BAA0B,EAAE,CAAC;4BAC5C,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;wBACzE,CAAC;oBACL,CAAC;oBACD,aAAa,GAAG,KAAK,CAAC;oBACtB,KAAK,GAAG,CAAC,CAAC;gBACd,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,aAAa,GAAG,KAAK,CAAC;gBACtB,KAAK,GAAG,CAAC,CAAC;YACd,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;YAEvE,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;YAC/C,QAAQ,CAAC,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAC/D,CAAC;QACD,IAAI,YAAY,EAAE,CAAC;YACf,YAAY,CAAC,mBAAmB,CAAC,OAAO,CAAC,GAAG,EAAE;gBAC1C,IAAI,cAAc,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,0BAA0B,IAAI,aAAa,EAAE,CAAC;oBACpF,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;oBACrE,cAAc,CAAC,uBAAuB,GAAG,IAAI,CAAC;gBAClD,CAAC;gBACD,QAAQ,CAAC,OAAO,EAAE,CAAC;YACvB,CAAC,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAEO,oBAAoB,CAAC,YAA8B;QACvD,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAChE,IAAI,aAAa,GAAG,KAAK,CAAC;QAC1B,MAAM,gBAAgB,GAAqB;YACvC,SAAS,EAAE,cAAc,CAAC,EAAE;YAC5B,WAAW,EAAE,IAAI;SACpB,CAAC;QACF,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,EAAE;YACjF,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,cAAc,CAAC,EAAE,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;YAChG,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,0BAA0B,IAAI,aAAa,CAAC,EAAE,CAAC;gBACtF,OAAO;YACX,CAAC;YACD,IAAI,CAAC,aAAa,EAAE,CAAC;gBACjB,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;gBACvE,cAAc,CAAC,oBAAoB,GAAG,IAAI,CAAC;gBAC3C,aAAa,GAAG,IAAI,CAAC;gBACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,0BAA0B,EAAE,CAAC;oBAC3C,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;gBACzE,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;YAC3E,CAAC;QACL,CAAC,CAAC,CAAC;QACH,YAAY,CAAC,mBAAmB,CAAC,OAAO,CAAC,GAAG,EAAE;YAC1C,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,cAAc,CAAC,EAAE,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;YAChG,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,GAAG,EAAE;gBACrC,IAAI,cAAc,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,uBAAuB,IAAI,aAAa,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,0BAA0B,EAAE,CAAC;oBAC/H,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;oBACrE,cAAc,CAAC,uBAAuB,GAAG,IAAI,CAAC;gBAClD,CAAC;YACL,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,4BAA4B,CAAC,YAA8B;QAC/D,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAChE,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,gBAAgB,GAAqB;YACvC,SAAS,EAAE,cAAc,CAAC,EAAE;YAC5B,WAAW,EAAE,IAAI;SACpB,CAAC;QACF,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,EAAE;YAC9D,cAAc,CAAC,YAAY,CAAC,QAAS,CAAC,eAAe,GAAG,IAAI,CAAC,sBAAsB,CAAC;YACpF,cAAc,CAAC,aAAa,CAAC,QAAS,CAAC,eAAe,GAAG,IAAI,CAAC,4BAA4B,CAAC;YAE9G,IAAI,cAAc,CAAC,IAAI,EAAE,CAAC;gBACtB,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,cAAc,CAAC,EAAE,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;gBAChG,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;YAC3E,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,YAAY,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,CAAC,gBAA+C,EAAE,EAAE;gBAC7D,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC;oBACjC,cAAc,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;gBACtG,CAAC;gBACD,IAAI,CAAC,cAAc,CAAC,kBAAkB,EAAE,CAAC;oBACrC,cAAc,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;gBAC5E,CAAC;gBAED,cAAc,CAAC,uBAAuB,GAAG,cAAc,CAAC,kBAAkB,CAAC,8BAA8B,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;oBACxH,IAAI,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;wBAC5B,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;wBAClD,IAAI,cAAc,CAAC,IAAI,EAAE,CAAC;4BACtB,IAAI,IAAI,CAAC,QAAQ,CAAC,sCAAsC,IAAI,YAAY,CAAC,QAAQ,KAAK,IAAI,CAAC,mBAAmB,EAAE,CAAC;gCAC7G,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,cAAc,CAAC,EAAE,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;gCAChG,IAAI,OAAO,EAAE,CAAC;oCACV,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;oCACvE,cAAc,CAAC,oBAAoB,GAAG,IAAI,CAAC;oCACxB,cAAc,CAAC,aAAa,CAAC,QAAS,CAAC,aAAa,GAAG,IAAI,CAAC,wBAAwB,CAAC;oCACrF,cAAc,CAAC,YAAY,CAAC,QAAS,CAAC,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC;gCAC1G,CAAC;qCAAM,CAAC;oCACJ,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;oCAClD,cAAc,CAAC,aAAa,CAAC,QAAS,CAAC,aAAa,GAAG,IAAI,CAAC,yBAAyB,CAAC;oCACtF,cAAc,CAAC,YAAY,CAAC,QAAS,CAAC,aAAa,GAAG,IAAI,CAAC,wBAAwB,CAAC;gCAC3G,CAAC;4BACL,CAAC;wBACL,CAAC;6BAAM,CAAC;4BACJ,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,sCAAsC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE,CAAC;gCAC1G,8CAA8C;gCAC9C,8CAA8C;gCAC9C,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;gCACnE,IAAI,cAAc,IAAI,cAAc,CAAC,oBAAoB,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,CAAC;oCACnG,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,cAAc,CAAC,EAAE,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;oCAChG,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,WAAW,EAAE,EAAE;wCAC7C,SAAS,EAAE,cAAc,CAAC,EAAE;wCAC5B,WAAW,EAAE,IAAI;qCACpB,CAAC,CAAC;oCACH,cAAc,CAAC,uBAAuB,GAAG,IAAI,CAAC;gCAClD,CAAC;gCACD,IAAI,CAAC,mBAAmB,GAAG,YAAY,CAAC,QAAQ,CAAC;4BACrD,CAAC;wBACL,CAAC;oBACL,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC,CAAC;YACF,IAAI,YAAY,CAAC,gBAAgB,EAAE,CAAC;gBAChC,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;YACxC,CAAC;iBAAM,CAAC;gBACJ,YAAY,CAAC,gCAAgC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC5D,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,oCAAoC;YACpC,MAAM,mBAAmB,GAAG,CAAC,KAAyB,EAAE,EAAE;gBACtD,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,OAAO,CAAC,GAAG,EAAE;oBACpD,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,cAAc,CAAC,EAAE,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;oBAChG,IAAI,cAAc,CAAC,YAAY,IAAI,KAAK,CAAC,WAAW,KAAK,cAAc,CAAC,YAAY,CAAC,WAAW,IAAI,cAAc,CAAC,IAAI,EAAE,CAAC;wBACtH,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;wBACvE,cAAc,CAAC,oBAAoB,GAAG,IAAI,CAAC;wBACxB,cAAc,CAAC,aAAa,CAAC,QAAS,CAAC,aAAa,GAAG,IAAI,CAAC,wBAAwB,CAAC;wBACrF,cAAc,CAAC,YAAY,CAAC,QAAS,CAAC,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC;oBAC1G,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC,CAAC;YAEF,MAAM,iBAAiB,GAAG,CAAC,KAAyB,EAAE,EAAE;gBACpD,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,OAAO,CAAC,GAAG,EAAE;oBACpD,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,cAAc,CAAC,EAAE,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;oBAChG,IAAI,cAAc,CAAC,YAAY,IAAI,KAAK,CAAC,WAAW,KAAK,cAAc,CAAC,YAAY,CAAC,WAAW,IAAI,cAAc,CAAC,IAAI,EAAE,CAAC;wBACtH,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;wBAClD,cAAc,CAAC,aAAa,CAAC,QAAS,CAAC,aAAa,GAAG,IAAI,CAAC,yBAAyB,CAAC;wBACtF,cAAc,CAAC,YAAY,CAAC,QAAS,CAAC,aAAa,GAAG,IAAI,CAAC,wBAAwB,CAAC;oBAC3G,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC,CAAC;YAEF,cAAc,CAAC,cAAc,GAAG;gBAC5B,SAAS,EAAE,iBAAiB;gBAC5B,WAAW,EAAE,mBAAmB;aACnC,CAAC;YAEF,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,gBAAgB,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAC;YACpF,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,gBAAgB,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QACpF,CAAC;IACL,CAAC;IAEO,8BAA8B,CAAC,MAAyB,EAAE,GAAQ;QACtE,IAAI,MAAM,EAAE,CAAC;YACT,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;YAC5D,IAAI,KAAK,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5B,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAEO,iBAAiB,CAAC,oBAA4B;QAClD,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC,oBAAoB,CAAC,CAAC;QAC/D,IAAI,CAAC,cAAc,EAAE,CAAC;YAClB,OAAO;QACX,CAAC;QACD,IAAI,cAAc,CAAC,kBAAkB,EAAE,CAAC;YACpC,IAAI,cAAc,CAAC,uBAAuB,EAAE,CAAC;gBACzC,cAAc,CAAC,kBAAkB,CAAC,8BAA8B,CAAC,MAAM,CAAC,cAAc,CAAC,uBAAuB,CAAC,CAAC;YACpH,CAAC;QACL,CAAC;QACD,IAAI,cAAc,CAAC,eAAe,EAAE,CAAC;YACjC,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,cAAc,CAAC,cAAc,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;YACxD,KAAK,MAAM,SAAS,IAAI,IAAI,EAAE,CAAC;gBAC3B,MAAM,IAAI,GAAG,cAAc,CAAC,cAAc,IAAI,cAAc,CAAC,cAAc,CAAC,SAAwB,CAAC,CAAC;gBACtG,IAAI,IAAI,EAAE,CAAC;oBACP,gEAAgE;oBAChE,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,mBAAmB,CAAC,SAAwB,EAAE,IAAW,CAAC,CAAC;gBAC9F,CAAC;YACL,CAAC;QACL,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,uBAAuB,IAAI,cAAc,CAAC,oBAAoB,EAAE,CAAC;YACjF,sEAAsE;YACtE,MAAM,gBAAgB,GAAqB;gBACvC,SAAS,EAAE,cAAc,CAAC,EAAE;gBAC5B,WAAW,EAAE,IAAI;aACpB,CAAC;YACF,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,GAAG,EAAE;gBACrC,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,cAAc,CAAC,EAAE,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;gBAChG,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,IAAI,IAAI,WAAW,EAAE,EAAE,gBAAgB,CAAC,CAAC;gBAC1F,cAAc,CAAC,uBAAuB,GAAG,IAAI,CAAC;YAClD,CAAC,CAAC,CAAC;QACP,CAAC;QACD,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,wBAAwB,CAAC,OAAO,CAAC,GAAG,EAAE;YAC/D,IAAI,CAAC;gBACD,cAAc,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;gBACvC,cAAc,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;gBACtC,sBAAsB;gBACtB,OAAO,IAAI,CAAC,YAAY,CAAC,oBAAoB,CAAC,CAAC;gBAC/C,IAAI,IAAI,CAAC,mBAAmB,KAAK,oBAAoB,EAAE,CAAC;oBACpD,8BAA8B;oBAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;oBAC5C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;wBACd,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;oBACvC,CAAC;yBAAM,CAAC;wBACJ,IAAI,CAAC,mBAAmB,GAAG,EAAE,CAAC;oBAClC,CAAC;gBACL,CAAC;YACL,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,KAAK,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;YAC/C,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,oBAAoB,CAAC,UAAgB;QACzC,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,uBAAuB,IAAI,oBAAoB,CAAC,mBAAmB,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1K,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,gCAAgC;YAC/D,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,gCAAgC,EAAE;YAClD,CAAC,CAAC,cAAc,CACV,cAAc,EACd;gBACI,MAAM,EAAE,CAAC;gBACT,WAAW,EAAE,MAAM;gBACnB,cAAc,EAAE,KAAK;gBACrB,YAAY,EAAE,EAAE;gBAChB,YAAY,EAAE,CAAC;aAClB,EACD,eAAe,CAClB,CAAC;QACR,YAAY,CAAC,MAAM,GAAG,UAAU,CAAC;QACjC,MAAM,oBAAoB,GAAG,IAAI,gBAAgB,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC;QACtF,oBAAoB,CAAC,aAAa,GAAG,IAAI,CAAC,wBAAwB,CAAC;QACnE,oBAAoB,CAAC,KAAK,GAAG,GAAG,CAAC;QACjC,YAAY,CAAC,QAAQ,GAAG,oBAAoB,CAAC;QAC7C,YAAY,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,sBAAsB,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QAC7C,YAAY,CAAC,UAAU,GAAG,KAAK,CAAC;QAChC,YAAY,CAAC,SAAS,GAAG,KAAK,CAAC;QAE/B,+CAA+C;QAC/C,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,4BAA4B;YAC5D,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,4BAA4B,EAAE;YAC9C,CAAC,CAAC,WAAW,CACP,aAAa,EACb;gBACI,QAAQ,EAAE,MAAM,GAAG,CAAC;gBACpB,SAAS,EAAE,MAAM,GAAG,CAAC;gBACrB,YAAY,EAAE,EAAE;aACnB,EACD,eAAe,CAClB,CAAC;QACR,aAAa,CAAC,gCAAgC,EAAE,CAAC;QACjD,aAAa,CAAC,UAAU,GAAG,KAAK,CAAC;QACjC,aAAa,CAAC,SAAS,GAAG,KAAK,CAAC;QAChC,MAAM,SAAS,GAAG,IAAI,gBAAgB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QACrE,SAAS,CAAC,aAAa,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;QACzC,SAAS,CAAC,aAAa,GAAG,IAAI,CAAC,yBAAyB,CAAC;QACzD,SAAS,CAAC,eAAe,GAAG,KAAK,CAAC;QAClC,aAAa,CAAC,QAAQ,GAAG,SAAS,CAAC;QAEnC,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;YAC/C,YAAY,CAAC,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;YAC/D,aAAa,CAAC,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QACpE,CAAC;QAED,OAAO;YACH,YAAY;YACZ,aAAa;SAChB,CAAC;IACN,CAAC;IAEO,aAAa,CAAC,OAAoB,EAAE,OAAoB;QAC5D,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC7F,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,OAAO,CAAC,WAAW,EAAE,aAAa,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACvF,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,CAAC;QACnK,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,0BAA0B,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC;QACxF,MAAM,MAAM,GAAG,IAAI,CAAC,wBAAwB,CAAC,MAAM,EAAE,CAAC;QACtD,IAAI,MAAM,GAAG,KAAK,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEO,sBAAsB,CAAC,aAA2B,EAAE,WAAmB,GAAG;QAC9E,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,QAAQ,CAAC;QACnC,wCAAwC;QACxC,IAAI,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC;YACnC,QAAQ,IAAI,CAAC,CAAC,CAAC;QACnB,CAAC;QACD,aAAa,CAAC,QAAQ,CAAC,CAAC,GAAG,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC;IACnD,CAAC;IAEO,mBAAmB,CAAC,gBAAkC,EAAE,EAAU,EAAE,iBAA4C;QACpH,gBAAgB,CAAC,SAAS,GAAG,EAAE,CAAC;QAChC,gBAAgB,CAAC,WAAW,GAAG,IAAI,CAAC;QACpC,IAAI,iBAAiB,EAAE,CAAC;YACpB,gBAAgB,CAAC,OAAO,GAAG,iBAAiB,CAAC,CAAC,CAAC;YAC/C,gBAAgB,CAAC,OAAO,GAAG,iBAAiB,CAAC,CAAC,CAAC;QACnD,CAAC;IACL,CAAC;IAED,gBAAgB;IAChB,IAAW,yBAAyB;QAChC,qBAAqB;QACrB,OAAO,IAAI,CAAC,wBAAwB,CAAC;IACzC,CAAC;;AAtxBc,0CAAU,GAAG,GAAG,AAAN,CAAO;AAyEhC;;GAEG;AACoB,oCAAI,GAAG,gBAAgB,CAAC,iBAAiB,AAArC,CAAsC;AACjE;;;;GAIG;AACoB,uCAAO,GAAG,CAAC,AAAJ,CAAK;AAusBvC,qBAAqB;AACrB,oBAAoB,CAAC,eAAe,CAChC,+BAA+B,CAAC,IAAI,EACpC,CAAC,gBAAgB,EAAE,OAAO,EAAE,EAAE;IAC1B,OAAO,GAAG,EAAE,CAAC,IAAI,+BAA+B,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;AAChF,CAAC,EACD,+BAA+B,CAAC,OAAO,EACvC,IAAI,CACP,CAAC","sourcesContent":["import { WebXRFeaturesManager, WebXRFeatureName } from \"../webXRFeaturesManager\";\r\nimport type { WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport type { AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport type { Observer } from \"../../Misc/observable\";\r\nimport type { WebXRInput } from \"../webXRInput\";\r\nimport type { WebXRInputSource } from \"../webXRInputSource\";\r\nimport type { Scene } from \"../../scene\";\r\nimport type { WebXRControllerComponent } from \"../motionController/webXRControllerComponent\";\r\nimport type { Nullable } from \"../../types\";\r\nimport { Matrix, Vector3 } from \"../../Maths/math.vector\";\r\nimport { Color3 } from \"../../Maths/math.color\";\r\nimport { Axis } from \"../../Maths/math.axis\";\r\nimport { StandardMaterial } from \"../../Materials/standardMaterial\";\r\nimport { CreateCylinder } from \"../../Meshes/Builders/cylinderBuilder\";\r\nimport { CreateTorus } from \"../../Meshes/Builders/torusBuilder\";\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 type { WebXRAbstractMotionController } from \"../motionController/webXRAbstractMotionController\";\r\nimport type { WebXRCamera } from \"../webXRCamera\";\r\nimport type { Node } from \"../../node\";\r\nimport { Viewport } from \"../../Maths/math.viewport\";\r\nimport type { Mesh } from \"../../Meshes/mesh\";\r\nimport { Tools } from \"../../Misc/tools\";\r\n\r\n/**\r\n * Options interface for the pointer selection module\r\n */\r\nexport interface IWebXRControllerPointerSelectionOptions {\r\n /**\r\n * if provided, this scene will be used to render meshes.\r\n */\r\n customUtilityLayerScene?: Scene;\r\n /**\r\n * Disable the pointer up event when the xr controller in screen and gaze mode is disposed (meaning - when the user removed the finger from the screen)\r\n * If not disabled, the last picked point will be used to execute a pointer up event\r\n * If disabled, pointer up event will be triggered right after the pointer down event.\r\n * Used in screen and gaze target ray mode only\r\n */\r\n disablePointerUpOnTouchOut: boolean;\r\n /**\r\n * For gaze mode for tracked-pointer / controllers (time to select instead of button press)\r\n */\r\n forceGazeMode: boolean;\r\n /**\r\n * Factor to be applied to the pointer-moved function in the gaze mode. How sensitive should the gaze mode be when checking if the pointer moved\r\n * to start a new countdown to the pointer down event.\r\n * Defaults to 1.\r\n */\r\n gazeModePointerMovedFactor?: number;\r\n /**\r\n * Different button type to use instead of the main component\r\n */\r\n overrideButtonId?: string;\r\n /**\r\n * use this rendering group id for the meshes (optional)\r\n */\r\n renderingGroupId?: number;\r\n /**\r\n * The amount of time in milliseconds it takes between pick found something to a pointer down event.\r\n * Used in gaze modes. Tracked pointer uses the trigger, screen uses touch events\r\n * 3000 means 3 seconds between pointing at something and selecting it\r\n */\r\n timeToSelect?: number;\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 * Optional WebXR camera to be used for gaze selection\r\n */\r\n gazeCamera?: WebXRCamera;\r\n /**\r\n * the xr input to use with this pointer selection\r\n */\r\n xrInput: WebXRInput;\r\n\r\n /**\r\n * Should the scene pointerX and pointerY update be disabled\r\n * This is required for fullscreen AR GUI, but might slow down other experiences.\r\n * Disable in VR, if not needed.\r\n * The first rig camera (left eye) will be used to calculate the projection\r\n */\r\n disableScenePointerVectorUpdate: boolean;\r\n\r\n /**\r\n * Enable pointer selection on all controllers instead of switching between them\r\n */\r\n enablePointerSelectionOnAllControllers?: boolean;\r\n\r\n /**\r\n * The preferred hand to give the pointer selection 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 /**\r\n * Disable switching the pointer selection 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 * The maximum distance of the pointer selection feature. Defaults to 100.\r\n */\r\n maxPointerDistance?: number;\r\n\r\n /**\r\n * A function that will be called when a new selection mesh is generated.\r\n * This function should return a mesh that will be used as the selection mesh.\r\n * The default is a torus with a 0.01 diameter and 0.0075 thickness .\r\n */\r\n customSelectionMeshGenerator?: () => Mesh;\r\n\r\n /**\r\n * A function that will be called when a new laser pointer mesh is generated.\r\n * This function should return a mesh that will be used as the laser pointer mesh.\r\n * The height (y) of the mesh must be 1.\r\n */\r\n customLasterPointerMeshGenerator?: () => AbstractMesh;\r\n\r\n /**\r\n * Use the grip space instead of the pointer space for selection, if available.\r\n */\r\n forceGripIfAvailable?: boolean;\r\n\r\n /**\r\n * If set to true, the hand rays will be disabled and the user will be able to look and pick objects.\r\n * This requires system support (like in the vision OS) and will not work in all systems.\r\n * @experimental - this is an experimental feature and might change int he future\r\n */\r\n lookAndPickMode?: boolean;\r\n}\r\n\r\n/**\r\n * A module that will enable pointer selection for motion controllers of XR Input Sources\r\n */\r\nexport class WebXRControllerPointerSelection 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\r\n const { laserPointer, selectionMesh } = this._generateNewMeshPair(this._options.forceGripIfAvailable && xrController.grip ? xrController.grip : xrController.pointer);\r\n\r\n // get two new meshes\r\n this._controllers[xrController.uniqueId] = {\r\n xrController,\r\n laserPointer,\r\n selectionMesh,\r\n meshUnderPointer: null,\r\n pick: null,\r\n tmpRay: new Ray(new Vector3(), new Vector3()),\r\n disabledByNearInteraction: false,\r\n id: WebXRControllerPointerSelection._IdCounter++,\r\n };\r\n\r\n if (this._attachedController) {\r\n if (\r\n !this._options.enablePointerSelectionOnAllControllers &&\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.enablePointerSelectionOnAllControllers) {\r\n this._attachedController = xrController.uniqueId;\r\n }\r\n }\r\n\r\n switch (xrController.inputSource.targetRayMode) {\r\n case \"tracked-pointer\":\r\n return this._attachTrackedPointerRayMode(xrController);\r\n case \"gaze\":\r\n return this._attachGazeMode(xrController);\r\n case \"screen\":\r\n case \"transient-pointer\":\r\n return this._attachScreenRayMode(xrController);\r\n }\r\n };\r\n\r\n private _controllers: {\r\n [controllerUniqueId: string]: {\r\n xrController?: WebXRInputSource;\r\n webXRCamera?: WebXRCamera;\r\n selectionComponent?: WebXRControllerComponent;\r\n onButtonChangedObserver?: Nullable<Observer<WebXRControllerComponent>>;\r\n onFrameObserver?: Nullable<Observer<XRFrame>>;\r\n laserPointer: AbstractMesh;\r\n selectionMesh: AbstractMesh;\r\n meshUnderPointer: Nullable<AbstractMesh>;\r\n pick: Nullable<PickingInfo>;\r\n id: number;\r\n tmpRay: Ray;\r\n disabledByNearInteraction: boolean;\r\n // event support\r\n eventListeners?: { [event in XREventType]?: (event: XRInputSourceEvent) => void };\r\n screenCoordinates?: { x: number; y: number };\r\n pointerDownTriggered?: boolean;\r\n finalPointerUpTriggered?: boolean;\r\n };\r\n } = {};\r\n private _scene: Scene;\r\n private _tmpVectorForPickCompare = new Vector3();\r\n\r\n private _attachedController: string;\r\n\r\n /**\r\n * The module's name\r\n */\r\n public static readonly Name = WebXRFeatureName.POINTER_SELECTION;\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 * Disable lighting on the laser pointer (so it will always be visible)\r\n */\r\n public disablePointerLighting: boolean = true;\r\n /**\r\n * Disable lighting on the selection mesh (so it will always be visible)\r\n */\r\n public disableSelectionMeshLighting: boolean = true;\r\n /**\r\n * Should the laser pointer be displayed\r\n */\r\n public displayLaserPointer: boolean = true;\r\n /**\r\n * Should the selection mesh be displayed (The ring at the end of the laser pointer)\r\n */\r\n public displaySelectionMesh: boolean = true;\r\n /**\r\n * This color will be set to the laser pointer when selection is triggered\r\n */\r\n public laserPointerPickedColor: Color3 = new Color3(0.9, 0.9, 0.9);\r\n /**\r\n * Default color of the laser pointer\r\n */\r\n public laserPointerDefaultColor: Color3 = new Color3(0.7, 0.7, 0.7);\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 * Optional filter to be used for ray selection. This predicate shares behavior with\r\n * scene.pointerMovePredicate which takes priority if it is also assigned.\r\n */\r\n public raySelectionPredicate: (mesh: AbstractMesh) => boolean;\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(\r\n _xrSessionManager: WebXRSessionManager,\r\n private readonly _options: IWebXRControllerPointerSelectionOptions\r\n ) {\r\n super(_xrSessionManager);\r\n this._scene = this._xrSessionManager.scene;\r\n\r\n // force look and pick mode if using WebXR on safari, assuming it is vision OS\r\n // Only if not explicitly set. If set to false, it will not be forced\r\n if (this._options.lookAndPickMode === undefined && (this._scene.getEngine()._badDesktopOS || this._scene.getEngine()._badOS)) {\r\n this._options.lookAndPickMode = true;\r\n }\r\n\r\n // look and pick mode extra state changes\r\n if (this._options.lookAndPickMode) {\r\n this._options.enablePointerSelectionOnAllControllers = true;\r\n this.displayLaserPointer = false;\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 override attach(): boolean {\r\n if (!super.attach()) {\r\n return false;\r\n }\r\n\r\n for (const controller of this._options.xrInput.controllers) {\r\n this._attachController(controller);\r\n }\r\n this._addNewAttachObserver(this._options.xrInput.onControllerAddedObservable, this._attachController, true);\r\n this._addNewAttachObserver(\r\n this._options.xrInput.onControllerRemovedObservable,\r\n (controller) => {\r\n // REMOVE the controller\r\n this._detachController(controller.uniqueId);\r\n },\r\n true\r\n );\r\n\r\n this._scene.constantlyUpdateMeshUnderPointer = true;\r\n\r\n if (this._options.gazeCamera) {\r\n const webXRCamera = this._options.gazeCamera;\r\n\r\n const { laserPointer, selectionMesh } = this._generateNewMeshPair(webXRCamera);\r\n\r\n this._controllers[\"camera\"] = {\r\n webXRCamera,\r\n laserPointer,\r\n selectionMesh,\r\n meshUnderPointer: null,\r\n pick: null,\r\n tmpRay: new Ray(new Vector3(), new Vector3()),\r\n disabledByNearInteraction: false,\r\n id: WebXRControllerPointerSelection._IdCounter++,\r\n };\r\n this._attachGazeMode();\r\n }\r\n\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 override detach(): boolean {\r\n if (!super.detach()) {\r\n return false;\r\n }\r\n const keys = Object.keys(this._controllers);\r\n for (const controllerId of keys) {\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 * @internal\r\n */\r\n public _getPointerSelectionDisabledByPointerId(id: number): boolean {\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]].disabledByNearInteraction;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _setPointerSelectionDisabledByPointerId(id: number, state: boolean) {\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 this._controllers[keys[i]].disabledByNearInteraction = state;\r\n return;\r\n }\r\n }\r\n }\r\n\r\n private _identityMatrix = Matrix.Identity();\r\n private _screenCoordinatesRef = Vector3.Zero();\r\n private _viewportRef = new Viewport(0, 0, 0, 0);\r\n\r\n protected _onXRFrame(_xrFrame: XRFrame) {\r\n const keys = Object.keys(this._controllers);\r\n for (const id of keys) {\r\n // look and pick mode\r\n // only do this for the selected pointer\r\n const controllerData = this._controllers[id];\r\n if (this._options.lookAndPickMode && controllerData.xrController?.inputSource.targetRayMode !== \"transient-pointer\") {\r\n continue;\r\n }\r\n if ((!this._options.enablePointerSelectionOnAllControllers && id !== this._attachedController) || controllerData.disabledByNearInteraction) {\r\n controllerData.selectionMesh.isVisible = false;\r\n controllerData.laserPointer.isVisible = false;\r\n controllerData.pick = null;\r\n continue;\r\n }\r\n\r\n controllerData.laserPointer.isVisible = this.displayLaserPointer;\r\n\r\n let controllerGlobalPosition: Vector3;\r\n\r\n // Every frame check collisions/input\r\n if (controllerData.xrController) {\r\n controllerGlobalPosition =\r\n this._options.forceGripIfAvailable && controllerData.xrController.grip\r\n ? controllerData.xrController.grip.position\r\n : controllerData.xrController.pointer.position;\r\n controllerData.xrController.getWorldPointerRayToRef(controllerData.tmpRay, this._options.forceGripIfAvailable);\r\n } else if (controllerData.webXRCamera) {\r\n controllerGlobalPosition = controllerData.webXRCamera.position;\r\n controllerData.webXRCamera.getForwardRayToRef(controllerData.tmpRay);\r\n } else {\r\n continue;\r\n }\r\n\r\n if (this._options.maxPointerDistance) {\r\n controllerData.tmpRay.length = this._options.maxPointerDistance;\r\n }\r\n // update pointerX and pointerY of the scene. Only if the flag is set to true!\r\n if (!this._options.disableScenePointerVectorUpdate && controllerGlobalPosition) {\r\n const scene = this._xrSessionManager.scene;\r\n const camera = this._options.xrInput.xrCamera;\r\n if (camera) {\r\n camera.viewport.toGlobalToRef(scene.getEngine().getRenderWidth() / camera.rigCameras.length, scene.getEngine().getRenderHeight(), this._viewportRef);\r\n Vector3.ProjectToRef(controllerGlobalPosition, this._identityMatrix, camera.getTransformationMatrix(), this._viewportRef, this._screenCoordinatesRef);\r\n // stay safe\r\n if (\r\n typeof this._screenCoordinatesRef.x === \"number\" &&\r\n typeof this._screenCoordinatesRef.y === \"number\" &&\r\n !isNaN(this._screenCoordinatesRef.x) &&\r\n !isNaN(this._screenCoordinatesRef.y) &&\r\n this._screenCoordinatesRef.x !== Infinity &&\r\n this._screenCoordinatesRef.y !== Infinity\r\n ) {\r\n scene.pointerX = this._screenCoordinatesRef.x;\r\n scene.pointerY = this._screenCoordinatesRef.y;\r\n\r\n controllerData.screenCoordinates = {\r\n x: this._screenCoordinatesRef.x,\r\n y: this._screenCoordinatesRef.y,\r\n };\r\n }\r\n }\r\n }\r\n\r\n let utilityScenePick = null;\r\n if (this._utilityLayerScene) {\r\n utilityScenePick = this._utilityLayerScene.pickWithRay(controllerData.tmpRay, this._utilityLayerScene.pointerMovePredicate || this.raySelectionPredicate);\r\n }\r\n\r\n const originalScenePick = this._scene.pickWithRay(controllerData.tmpRay, this._scene.pointerMovePredicate || this.raySelectionPredicate);\r\n if (!utilityScenePick || !utilityScenePick.hit) {\r\n // No hit in utility scene\r\n controllerData.pick = originalScenePick;\r\n } else if (!originalScenePick || !originalScenePick.hit) {\r\n // No hit in original scene\r\n controllerData.pick = utilityScenePick;\r\n } else if (utilityScenePick.distance < originalScenePick.distance) {\r\n // Hit is closer in utility scene\r\n controllerData.pick = utilityScenePick;\r\n } else {\r\n // Hit is closer in original scene\r\n controllerData.pick = originalScenePick;\r\n }\r\n\r\n if (controllerData.pick && controllerData.xrController) {\r\n controllerData.pick.aimTransform = controllerData.xrController.pointer;\r\n controllerData.pick.gripTransform = controllerData.xrController.grip || null;\r\n controllerData.pick.originMesh = controllerData.xrController.pointer;\r\n controllerData.tmpRay.length = controllerData.pick.distance;\r\n }\r\n\r\n const pick = controllerData.pick;\r\n\r\n if (pick && pick.pickedPoint && pick.hit) {\r\n // Update laser state\r\n this._updatePointerDistance(controllerData.laserPointer, pick.distance);\r\n\r\n // Update cursor state\r\n controllerData.selectionMesh.position.copyFrom(pick.pickedPoint);\r\n controllerData.selectionMesh.scaling.x = Math.sqrt(pick.distance);\r\n controllerData.selectionMesh.scaling.y = Math.sqrt(pick.distance);\r\n controllerData.selectionMesh.scaling.z = Math.sqrt(pick.distance);\r\n\r\n // To avoid z-fighting\r\n const pickNormal = this._convertNormalToDirectionOfRay(pick.getNormal(true), controllerData.tmpRay);\r\n const deltaFighting = 0.001;\r\n controllerData.selectionMesh.position.copyFrom(pick.pickedPoint);\r\n if (pickNormal) {\r\n const axis1 = Vector3.Cross(Axis.Y, pickNormal);\r\n const axis2 = Vector3.Cross(pickNormal, axis1);\r\n Vector3.RotationFromAxisToRef(axis2, pickNormal, axis1, controllerData.selectionMesh.rotation);\r\n controllerData.selectionMesh.position.addInPlace(pickNormal.scale(deltaFighting));\r\n }\r\n controllerData.selectionMesh.isVisible = this.displaySelectionMesh;\r\n controllerData.meshUnderPointer = pick.pickedMesh;\r\n } else {\r\n controllerData.selectionMesh.isVisible = false;\r\n this._updatePointerDistance(controllerData.laserPointer, 1);\r\n controllerData.meshUnderPointer = null;\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 _attachGazeMode(xrController?: WebXRInputSource) {\r\n const controllerData = this._controllers[(xrController && xrController.uniqueId) || \"camera\"];\r\n // attached when touched, detaches when raised\r\n const timeToSelect = this._options.timeToSelect || 3000;\r\n const sceneToRenderTo = this._options.useUtilityLayer ? this._utilityLayerScene : this._scene;\r\n let oldPick = new PickingInfo();\r\n const discMesh = CreateTorus(\r\n \"selection\",\r\n {\r\n diameter: 0.0035 * 15,\r\n thickness: 0.0025 * 6,\r\n tessellation: 20,\r\n },\r\n sceneToRenderTo\r\n );\r\n discMesh.isVisible = false;\r\n discMesh.isPickable = false;\r\n discMesh.parent = controllerData.selectionMesh;\r\n let timer = 0;\r\n let downTriggered = false;\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 (!controllerData.pick) {\r\n return;\r\n }\r\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n controllerData.laserPointer.material!.alpha = 0;\r\n discMesh.isVisible = false;\r\n if (controllerData.pick.hit) {\r\n if (!this._pickingMoved(oldPick, controllerData.pick)) {\r\n if (timer > timeToSelect / 10) {\r\n discMesh.isVisible = true;\r\n }\r\n\r\n timer += this._scene.getEngine().getDeltaTime();\r\n if (timer >= timeToSelect) {\r\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n // this pointerdown event is not setting the controllerData.pointerDownTriggered to avoid a pointerUp event when this feature is detached\r\n downTriggered = true;\r\n // pointer up right after down, if disable on touch out\r\n if (this._options.disablePointerUpOnTouchOut) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n }\r\n discMesh.isVisible = false;\r\n } else {\r\n const scaleFactor = 1 - timer / timeToSelect;\r\n discMesh.scaling.set(scaleFactor, scaleFactor, scaleFactor);\r\n }\r\n } else {\r\n if (downTriggered) {\r\n if (!this._options.disablePointerUpOnTouchOut) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n }\r\n }\r\n downTriggered = false;\r\n timer = 0;\r\n }\r\n } else {\r\n downTriggered = false;\r\n timer = 0;\r\n }\r\n\r\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\r\n\r\n oldPick = controllerData.pick;\r\n });\r\n\r\n if (this._options.renderingGroupId !== undefined) {\r\n discMesh.renderingGroupId = this._options.renderingGroupId;\r\n }\r\n if (xrController) {\r\n xrController.onDisposeObservable.addOnce(() => {\r\n if (controllerData.pick && !this._options.disablePointerUpOnTouchOut && downTriggered) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n controllerData.finalPointerUpTriggered = true;\r\n }\r\n discMesh.dispose();\r\n });\r\n }\r\n }\r\n\r\n private _attachScreenRayMode(xrController: WebXRInputSource) {\r\n const controllerData = this._controllers[xrController.uniqueId];\r\n let downTriggered = false;\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 this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n if (!controllerData.pick || (this._options.disablePointerUpOnTouchOut && downTriggered)) {\r\n return;\r\n }\r\n if (!downTriggered) {\r\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n controllerData.pointerDownTriggered = true;\r\n downTriggered = true;\r\n if (this._options.disablePointerUpOnTouchOut) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n }\r\n } else {\r\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\r\n }\r\n });\r\n xrController.onDisposeObservable.addOnce(() => {\r\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n this._xrSessionManager.runInXRFrame(() => {\r\n if (controllerData.pick && !controllerData.finalPointerUpTriggered && downTriggered && !this._options.disablePointerUpOnTouchOut) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n controllerData.finalPointerUpTriggered = true;\r\n }\r\n });\r\n });\r\n }\r\n\r\n private _attachTrackedPointerRayMode(xrController: WebXRInputSource) {\r\n const controllerData = this._controllers[xrController.uniqueId];\r\n if (this._options.forceGazeMode) {\r\n return this._attachGazeMode(xrController);\r\n }\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 (<StandardMaterial>controllerData.laserPointer.material).disableLighting = this.disablePointerLighting;\r\n (<StandardMaterial>controllerData.selectionMesh.material).disableLighting = this.disableSelectionMeshLighting;\r\n\r\n if (controllerData.pick) {\r\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\r\n }\r\n });\r\n if (xrController.inputSource.gamepad) {\r\n const init = (motionController: WebXRAbstractMotionController) => {\r\n if (this._options.overrideButtonId) {\r\n controllerData.selectionComponent = motionController.getComponent(this._options.overrideButtonId);\r\n }\r\n if (!controllerData.selectionComponent) {\r\n controllerData.selectionComponent = motionController.getMainComponent();\r\n }\r\n\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 if (controllerData.pick) {\r\n if (this._options.enablePointerSelectionOnAllControllers || xrController.uniqueId === this._attachedController) {\r\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n if (pressed) {\r\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n controllerData.pointerDownTriggered = true;\r\n (<StandardMaterial>controllerData.selectionMesh.material).emissiveColor = this.selectionMeshPickedColor;\r\n (<StandardMaterial>controllerData.laserPointer.material).emissiveColor = this.laserPointerPickedColor;\r\n } else {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n (<StandardMaterial>controllerData.selectionMesh.material).emissiveColor = this.selectionMeshDefaultColor;\r\n (<StandardMaterial>controllerData.laserPointer.material).emissiveColor = this.laserPointerDefaultColor;\r\n }\r\n }\r\n } else {\r\n if (pressed && !this._options.enablePointerSelectionOnAllControllers && !this._options.disableSwitchOnClick) {\r\n // force a pointer up if switching controllers\r\n // get the controller that was attached before\r\n const prevController = this._controllers[this._attachedController];\r\n if (prevController && prevController.pointerDownTriggered && !prevController.finalPointerUpTriggered) {\r\n this._augmentPointerInit(pointerEventInit, prevController.id, prevController.screenCoordinates);\r\n this._scene.simulatePointerUp(new PickingInfo(), {\r\n pointerId: prevController.id,\r\n pointerType: \"xr\",\r\n });\r\n prevController.finalPointerUpTriggered = true;\r\n }\r\n this._attachedController = xrController.uniqueId;\r\n }\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 this._xrSessionManager.onXRFrameObservable.addOnce(() => {\r\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick) {\r\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n controllerData.pointerDownTriggered = true;\r\n (<StandardMaterial>controllerData.selectionMesh.material).emissiveColor = this.selectionMeshPickedColor;\r\n (<StandardMaterial>controllerData.laserPointer.material).emissiveColor = this.laserPointerPickedColor;\r\n }\r\n });\r\n };\r\n\r\n const selectEndListener = (event: XRInputSourceEvent) => {\r\n this._xrSessionManager.onXRFrameObservable.addOnce(() => {\r\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n (<StandardMaterial>controllerData.selectionMesh.material).emissiveColor = this.selectionMeshDefaultColor;\r\n (<StandardMaterial>controllerData.laserPointer.material).emissiveColor = this.laserPointerDefaultColor;\r\n }\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 _convertNormalToDirectionOfRay(normal: Nullable<Vector3>, ray: Ray) {\r\n if (normal) {\r\n const angle = Math.acos(Vector3.Dot(normal, ray.direction));\r\n if (angle < Math.PI / 2) {\r\n normal.scaleInPlace(-1);\r\n }\r\n }\r\n return normal;\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.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 const keys = Object.keys(controllerData.eventListeners);\r\n for (const eventName of keys) {\r\n const func = controllerData.eventListeners && controllerData.eventListeners[eventName as XREventType];\r\n if (func) {\r\n // For future reference - this is an issue in the WebXR typings.\r\n this._xrSessionManager.session.removeEventListener(eventName as XREventType, func as any);\r\n }\r\n }\r\n }\r\n\r\n if (!controllerData.finalPointerUpTriggered && controllerData.pointerDownTriggered) {\r\n // Stay safe and fire a pointerup, in case it wasn't already triggered\r\n const pointerEventInit: PointerEventInit = {\r\n pointerId: controllerData.id,\r\n pointerType: \"xr\",\r\n };\r\n this._xrSessionManager.runInXRFrame(() => {\r\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n this._scene.simulatePointerUp(controllerData.pick || new PickingInfo(), pointerEventInit);\r\n controllerData.finalPointerUpTriggered = true;\r\n });\r\n }\r\n this._xrSessionManager.scene.onBeforeRenderObservable.addOnce(() => {\r\n try {\r\n controllerData.selectionMesh.dispose();\r\n controllerData.laserPointer.dispose();\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 } catch (e) {\r\n Tools.Warn(\"controller already detached.\");\r\n }\r\n });\r\n }\r\n\r\n private _generateNewMeshPair(meshParent: Node) {\r\n const sceneToRenderTo = this._options.useUtilityLayer ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene : this._scene;\r\n const laserPointer = this._options.customLasterPointerMeshGenerator\r\n ? this._options.customLasterPointerMeshGenerator()\r\n : CreateCylinder(\r\n \"laserPointer\",\r\n {\r\n height: 1,\r\n diameterTop: 0.0002,\r\n diameterBottom: 0.004,\r\n tessellation: 20,\r\n subdivisions: 1,\r\n },\r\n sceneToRenderTo\r\n );\r\n laserPointer.parent = meshParent;\r\n const laserPointerMaterial = new StandardMaterial(\"laserPointerMat\", sceneToRenderTo);\r\n laserPointerMaterial.emissiveColor = this.laserPointerDefaultColor;\r\n laserPointerMaterial.alpha = 0.7;\r\n laserPointer.material = laserPointerMaterial;\r\n laserPointer.rotation.x = Math.PI / 2;\r\n this._updatePointerDistance(laserPointer, 1);\r\n laserPointer.isPickable = false;\r\n laserPointer.isVisible = false;\r\n\r\n // Create a gaze tracker for the XR controller\r\n const selectionMesh = this._options.customSelectionMeshGenerator\r\n ? this._options.customSelectionMeshGenerator()\r\n : CreateTorus(\r\n \"gazeTracker\",\r\n {\r\n diameter: 0.0035 * 3,\r\n thickness: 0.0025 * 3,\r\n tessellation: 20,\r\n },\r\n sceneToRenderTo\r\n );\r\n selectionMesh.bakeCurrentTransformIntoVertices();\r\n selectionMesh.isPickable = false;\r\n selectionMesh.isVisible = false;\r\n const 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 if (this._options.renderingGroupId !== undefined) {\r\n laserPointer.renderingGroupId = this._options.renderingGroupId;\r\n selectionMesh.renderingGroupId = this._options.renderingGroupId;\r\n }\r\n\r\n return {\r\n laserPointer,\r\n selectionMesh,\r\n };\r\n }\r\n\r\n private _pickingMoved(oldPick: PickingInfo, newPick: PickingInfo) {\r\n if (!oldPick.hit || !newPick.hit) {\r\n return true;\r\n }\r\n if (!oldPick.pickedMesh || !oldPick.pickedPoint || !newPick.pickedMesh || !newPick.pickedPoint) {\r\n return true;\r\n }\r\n if (oldPick.pickedMesh !== newPick.pickedMesh) {\r\n return true;\r\n }\r\n oldPick.pickedPoint?.subtractToRef(newPick.pickedPoint, this._tmpVectorForPickCompare);\r\n this._tmpVectorForPickCompare.set(Math.abs(this._tmpVectorForPickCompare.x), Math.abs(this._tmpVectorForPickCompare.y), Math.abs(this._tmpVectorForPickCompare.z));\r\n const delta = (this._options.gazeModePointerMovedFactor || 1) * 0.01 * newPick.distance;\r\n const length = this._tmpVectorForPickCompare.length();\r\n if (length > delta) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n private _updatePointerDistance(_laserPointer: AbstractMesh, distance: number = 100) {\r\n _laserPointer.scaling.y = distance;\r\n // a bit of distance from the controller\r\n if (this._scene.useRightHandedSystem) {\r\n distance *= -1;\r\n }\r\n _laserPointer.position.z = distance / 2 + 0.05;\r\n }\r\n\r\n private _augmentPointerInit(pointerEventInit: PointerEventInit, id: number, screenCoordinates?: { x: number; y: number }): void {\r\n pointerEventInit.pointerId = id;\r\n pointerEventInit.pointerType = \"xr\";\r\n if (screenCoordinates) {\r\n pointerEventInit.screenX = screenCoordinates.x;\r\n pointerEventInit.screenY = screenCoordinates.y;\r\n }\r\n }\r\n\r\n /** @internal */\r\n public get lasterPointerDefaultColor(): Color3 {\r\n // here due to a typo\r\n return this.laserPointerDefaultColor;\r\n }\r\n}\r\n\r\n//register the plugin\r\nWebXRFeaturesManager.AddWebXRFeature(\r\n WebXRControllerPointerSelection.Name,\r\n (xrSessionManager, options) => {\r\n return () => new WebXRControllerPointerSelection(xrSessionManager, options);\r\n },\r\n WebXRControllerPointerSelection.Version,\r\n true\r\n);\r\n"]}
|
|
1
|
+
{"version":3,"file":"WebXRControllerPointerSelection.js","sourceRoot":"","sources":["../../../../../dev/core/src/XR/features/WebXRControllerPointerSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebXRFeaturesManager, WebXRFeatureName } from \"../webXRFeaturesManager\";\r\nimport type { WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport type { AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport type { Observer } from \"../../Misc/observable\";\r\nimport type { WebXRInput } from \"../webXRInput\";\r\nimport type { WebXRInputSource } from \"../webXRInputSource\";\r\nimport type { Scene } from \"../../scene\";\r\nimport type { WebXRControllerComponent } from \"../motionController/webXRControllerComponent\";\r\nimport type { Nullable } from \"../../types\";\r\nimport { Matrix, Vector3 } from \"../../Maths/math.vector\";\r\nimport { Color3 } from \"../../Maths/math.color\";\r\nimport { Axis } from \"../../Maths/math.axis\";\r\nimport { StandardMaterial } from \"../../Materials/standardMaterial\";\r\nimport { CreateCylinder } from \"../../Meshes/Builders/cylinderBuilder\";\r\nimport { CreateTorus } from \"../../Meshes/Builders/torusBuilder\";\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 type { WebXRAbstractMotionController } from \"../motionController/webXRAbstractMotionController\";\r\nimport type { WebXRCamera } from \"../webXRCamera\";\r\nimport type { Node } from \"../../node\";\r\nimport { Viewport } from \"../../Maths/math.viewport\";\r\nimport type { Mesh } from \"../../Meshes/mesh\";\r\nimport { Tools } from \"../../Misc/tools\";\r\n\r\n/**\r\n * Options interface for the pointer selection module\r\n */\r\nexport interface IWebXRControllerPointerSelectionOptions {\r\n /**\r\n * if provided, this scene will be used to render meshes.\r\n */\r\n customUtilityLayerScene?: Scene;\r\n /**\r\n * Disable the pointer up event when the xr controller in screen and gaze mode is disposed (meaning - when the user removed the finger from the screen)\r\n * If not disabled, the last picked point will be used to execute a pointer up event\r\n * If disabled, pointer up event will be triggered right after the pointer down event.\r\n * Used in screen and gaze target ray mode only\r\n */\r\n disablePointerUpOnTouchOut: boolean;\r\n /**\r\n * For gaze mode for tracked-pointer / controllers (time to select instead of button press)\r\n */\r\n forceGazeMode: boolean;\r\n /**\r\n * Factor to be applied to the pointer-moved function in the gaze mode. How sensitive should the gaze mode be when checking if the pointer moved\r\n * to start a new countdown to the pointer down event.\r\n * Defaults to 1.\r\n */\r\n gazeModePointerMovedFactor?: number;\r\n /**\r\n * Different button type to use instead of the main component\r\n */\r\n overrideButtonId?: string;\r\n /**\r\n * use this rendering group id for the meshes (optional)\r\n */\r\n renderingGroupId?: number;\r\n /**\r\n * The amount of time in milliseconds it takes between pick found something to a pointer down event.\r\n * Used in gaze modes. Tracked pointer uses the trigger, screen uses touch events\r\n * 3000 means 3 seconds between pointing at something and selecting it\r\n */\r\n timeToSelect?: number;\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 * Optional WebXR camera to be used for gaze selection\r\n */\r\n gazeCamera?: WebXRCamera;\r\n /**\r\n * the xr input to use with this pointer selection\r\n */\r\n xrInput: WebXRInput;\r\n\r\n /**\r\n * Should the scene pointerX and pointerY update be disabled\r\n * This is required for fullscreen AR GUI, but might slow down other experiences.\r\n * Disable in VR, if not needed.\r\n * The first rig camera (left eye) will be used to calculate the projection\r\n */\r\n disableScenePointerVectorUpdate: boolean;\r\n\r\n /**\r\n * Enable pointer selection on all controllers instead of switching between them\r\n */\r\n enablePointerSelectionOnAllControllers?: boolean;\r\n\r\n /**\r\n * The preferred hand to give the pointer selection 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 /**\r\n * Disable switching the pointer selection 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 * The maximum distance of the pointer selection feature. Defaults to 100.\r\n */\r\n maxPointerDistance?: number;\r\n\r\n /**\r\n * A function that will be called when a new selection mesh is generated.\r\n * This function should return a mesh that will be used as the selection mesh.\r\n * The default is a torus with a 0.01 diameter and 0.0075 thickness .\r\n */\r\n customSelectionMeshGenerator?: () => Mesh;\r\n\r\n /**\r\n * A function that will be called when a new laser pointer mesh is generated.\r\n * This function should return a mesh that will be used as the laser pointer mesh.\r\n * The height (y) of the mesh must be 1.\r\n */\r\n customLasterPointerMeshGenerator?: () => AbstractMesh;\r\n\r\n /**\r\n * Use the grip space instead of the pointer space for selection, if available.\r\n */\r\n forceGripIfAvailable?: boolean;\r\n\r\n /**\r\n * If set to true, the hand rays will be disabled and the user will be able to look and pick objects.\r\n * This requires system support (like in the vision OS) and will not work in all systems.\r\n * @experimental - this is an experimental feature and might change int he future\r\n */\r\n lookAndPickMode?: boolean;\r\n}\r\n\r\n/**\r\n * A module that will enable pointer selection for motion controllers of XR Input Sources\r\n */\r\nexport class WebXRControllerPointerSelection 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\r\n const { laserPointer, selectionMesh } = this._generateNewMeshPair(this._options.forceGripIfAvailable && xrController.grip ? xrController.grip : xrController.pointer);\r\n\r\n // get two new meshes\r\n this._controllers[xrController.uniqueId] = {\r\n xrController,\r\n laserPointer,\r\n selectionMesh,\r\n meshUnderPointer: null,\r\n pick: null,\r\n tmpRay: new Ray(new Vector3(), new Vector3()),\r\n disabledByNearInteraction: false,\r\n id: WebXRControllerPointerSelection._IdCounter++,\r\n };\r\n\r\n if (this._attachedController) {\r\n if (\r\n !this._options.enablePointerSelectionOnAllControllers &&\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.enablePointerSelectionOnAllControllers) {\r\n this._attachedController = xrController.uniqueId;\r\n }\r\n }\r\n\r\n switch (xrController.inputSource.targetRayMode) {\r\n case \"tracked-pointer\":\r\n return this._attachTrackedPointerRayMode(xrController);\r\n case \"gaze\":\r\n return this._attachGazeMode(xrController);\r\n case \"screen\":\r\n case \"transient-pointer\":\r\n return this._attachScreenRayMode(xrController);\r\n }\r\n };\r\n\r\n private _controllers: {\r\n [controllerUniqueId: string]: {\r\n xrController?: WebXRInputSource;\r\n webXRCamera?: WebXRCamera;\r\n selectionComponent?: WebXRControllerComponent;\r\n onButtonChangedObserver?: Nullable<Observer<WebXRControllerComponent>>;\r\n onFrameObserver?: Nullable<Observer<XRFrame>>;\r\n laserPointer: AbstractMesh;\r\n selectionMesh: AbstractMesh;\r\n meshUnderPointer: Nullable<AbstractMesh>;\r\n pick: Nullable<PickingInfo>;\r\n id: number;\r\n tmpRay: Ray;\r\n disabledByNearInteraction: boolean;\r\n // event support\r\n eventListeners?: { [event in XREventType]?: (event: XRInputSourceEvent) => void };\r\n screenCoordinates?: { x: number; y: number };\r\n pointerDownTriggered?: boolean;\r\n finalPointerUpTriggered?: boolean;\r\n };\r\n } = {};\r\n private _scene: Scene;\r\n private _tmpVectorForPickCompare = new Vector3();\r\n\r\n private _attachedController: string;\r\n\r\n /**\r\n * The module's name\r\n */\r\n public static readonly Name = WebXRFeatureName.POINTER_SELECTION;\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 * Disable lighting on the laser pointer (so it will always be visible)\r\n */\r\n public disablePointerLighting: boolean = true;\r\n /**\r\n * Disable lighting on the selection mesh (so it will always be visible)\r\n */\r\n public disableSelectionMeshLighting: boolean = true;\r\n /**\r\n * Should the laser pointer be displayed\r\n */\r\n public displayLaserPointer: boolean = true;\r\n /**\r\n * Should the selection mesh be displayed (The ring at the end of the laser pointer)\r\n */\r\n public displaySelectionMesh: boolean = true;\r\n /**\r\n * This color will be set to the laser pointer when selection is triggered\r\n */\r\n public laserPointerPickedColor: Color3 = new Color3(0.9, 0.9, 0.9);\r\n /**\r\n * Default color of the laser pointer\r\n */\r\n public laserPointerDefaultColor: Color3 = new Color3(0.7, 0.7, 0.7);\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 * Optional filter to be used for ray selection. This predicate shares behavior with\r\n * scene.pointerMovePredicate which takes priority if it is also assigned.\r\n */\r\n public raySelectionPredicate: (mesh: AbstractMesh) => boolean;\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(\r\n _xrSessionManager: WebXRSessionManager,\r\n private readonly _options: IWebXRControllerPointerSelectionOptions\r\n ) {\r\n super(_xrSessionManager);\r\n this._scene = this._xrSessionManager.scene;\r\n\r\n // force look and pick mode if using WebXR on safari, assuming it is vision OS\r\n // Only if not explicitly set. If set to false, it will not be forced\r\n if (this._options.lookAndPickMode === undefined && (this._scene.getEngine()._badDesktopOS || this._scene.getEngine()._badOS)) {\r\n this._options.lookAndPickMode = true;\r\n }\r\n\r\n // look and pick mode extra state changes\r\n if (this._options.lookAndPickMode) {\r\n this._options.enablePointerSelectionOnAllControllers = true;\r\n this.displayLaserPointer = false;\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 override attach(): boolean {\r\n if (!super.attach()) {\r\n return false;\r\n }\r\n\r\n for (const controller of this._options.xrInput.controllers) {\r\n this._attachController(controller);\r\n }\r\n this._addNewAttachObserver(this._options.xrInput.onControllerAddedObservable, this._attachController, true);\r\n this._addNewAttachObserver(\r\n this._options.xrInput.onControllerRemovedObservable,\r\n (controller) => {\r\n // REMOVE the controller\r\n this._detachController(controller.uniqueId);\r\n },\r\n true\r\n );\r\n\r\n this._scene.constantlyUpdateMeshUnderPointer = true;\r\n\r\n if (this._options.gazeCamera) {\r\n const webXRCamera = this._options.gazeCamera;\r\n\r\n const { laserPointer, selectionMesh } = this._generateNewMeshPair(webXRCamera);\r\n\r\n this._controllers[\"camera\"] = {\r\n webXRCamera,\r\n laserPointer,\r\n selectionMesh,\r\n meshUnderPointer: null,\r\n pick: null,\r\n tmpRay: new Ray(new Vector3(), new Vector3()),\r\n disabledByNearInteraction: false,\r\n id: WebXRControllerPointerSelection._IdCounter++,\r\n };\r\n this._attachGazeMode();\r\n }\r\n\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 override detach(): boolean {\r\n if (!super.detach()) {\r\n return false;\r\n }\r\n const keys = Object.keys(this._controllers);\r\n for (const controllerId of keys) {\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 unique id of the currently attached (active) controller for pointer selection.\r\n * When `enablePointerSelectionOnAllControllers` is true, this value is not meaningful\r\n * because all controllers are active simultaneously.\r\n * @returns the unique id of the attached controller, or an empty string if none is attached\r\n */\r\n public get attachedControllerId(): string {\r\n return this._attachedController || \"\";\r\n }\r\n\r\n /**\r\n * Set the active controller for pointer selection during an XR session.\r\n * Accepts either an `XRHandedness` value (`\"left\"`, `\"right\"`, `\"none\"`) to select\r\n * the first matching controller, or a controller unique id string for precise control.\r\n *\r\n * When a matching controller is found, any in-progress pointer-down state on the\r\n * previously active controller is properly resolved (pointer-up is simulated).\r\n *\r\n * This also updates the `preferredHandedness` option so that if controllers are\r\n * re-initialized (e.g. on disconnect/reconnect), the new preference persists.\r\n *\r\n * This method is a no-op when `enablePointerSelectionOnAllControllers` is true,\r\n * since all controllers are active simultaneously in that mode.\r\n *\r\n * @param controllerId the XRHandedness (`\"left\"`, `\"right\"`, `\"none\"`) or the unique id of the controller to attach\r\n * @returns true if the active controller was changed, false otherwise\r\n */\r\n public setAttachedController(controllerId: XRHandedness | string): boolean {\r\n if (this._options.enablePointerSelectionOnAllControllers) {\r\n return false;\r\n }\r\n\r\n let targetUniqueId: string | undefined;\r\n\r\n // Check if controllerId matches a known handedness value\r\n if (controllerId === \"left\" || controllerId === \"right\" || controllerId === \"none\") {\r\n // Find the first controller that matches the given handedness\r\n for (const id in this._controllers) {\r\n const data = this._controllers[id];\r\n if (data.xrController && data.xrController.inputSource.handedness === controllerId) {\r\n targetUniqueId = id;\r\n break;\r\n }\r\n }\r\n } else {\r\n // Treat as a controller unique id\r\n if (this._controllers[controllerId]) {\r\n targetUniqueId = controllerId;\r\n }\r\n }\r\n\r\n if (!targetUniqueId || targetUniqueId === this._attachedController) {\r\n return false;\r\n }\r\n\r\n // Update preferredHandedness only after confirming the switch will happen\r\n if (controllerId === \"left\" || controllerId === \"right\" || controllerId === \"none\") {\r\n (this._options as IWebXRControllerPointerSelectionOptions).preferredHandedness = controllerId;\r\n } else {\r\n const targetData = this._controllers[targetUniqueId];\r\n if (targetData.xrController) {\r\n (this._options as IWebXRControllerPointerSelectionOptions).preferredHandedness = targetData.xrController.inputSource.handedness;\r\n }\r\n }\r\n\r\n // Properly finalize pointer state on the previous controller\r\n const prevControllerData = this._controllers[this._attachedController];\r\n if (prevControllerData && prevControllerData.pointerDownTriggered && !prevControllerData.finalPointerUpTriggered && this._scene.isPointerCaptured(prevControllerData.id)) {\r\n const pointerEventInit: PointerEventInit = {\r\n pointerId: prevControllerData.id,\r\n pointerType: \"xr\",\r\n };\r\n this._augmentPointerInit(pointerEventInit, prevControllerData.id, prevControllerData.screenCoordinates);\r\n this._scene.simulatePointerUp(prevControllerData.pick || new PickingInfo(), pointerEventInit);\r\n prevControllerData.pointerDownTriggered = false;\r\n prevControllerData.finalPointerUpTriggered = true;\r\n }\r\n\r\n this._attachedController = targetUniqueId;\r\n return true;\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 * @internal\r\n */\r\n public _getPointerSelectionDisabledByPointerId(id: number): boolean {\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]].disabledByNearInteraction;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _setPointerSelectionDisabledByPointerId(id: number, state: boolean) {\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 this._controllers[keys[i]].disabledByNearInteraction = state;\r\n return;\r\n }\r\n }\r\n }\r\n\r\n private _identityMatrix = Matrix.Identity();\r\n private _screenCoordinatesRef = Vector3.Zero();\r\n private _viewportRef = new Viewport(0, 0, 0, 0);\r\n\r\n protected _onXRFrame(_xrFrame: XRFrame) {\r\n const keys = Object.keys(this._controllers);\r\n for (const id of keys) {\r\n // look and pick mode\r\n // only do this for the selected pointer\r\n const controllerData = this._controllers[id];\r\n if (this._options.lookAndPickMode && controllerData.xrController?.inputSource.targetRayMode !== \"transient-pointer\") {\r\n continue;\r\n }\r\n if ((!this._options.enablePointerSelectionOnAllControllers && id !== this._attachedController) || controllerData.disabledByNearInteraction) {\r\n controllerData.selectionMesh.isVisible = false;\r\n controllerData.laserPointer.isVisible = false;\r\n controllerData.pick = null;\r\n continue;\r\n }\r\n\r\n controllerData.laserPointer.isVisible = this.displayLaserPointer;\r\n\r\n let controllerGlobalPosition: Vector3;\r\n\r\n // Every frame check collisions/input\r\n if (controllerData.xrController) {\r\n controllerGlobalPosition =\r\n this._options.forceGripIfAvailable && controllerData.xrController.grip\r\n ? controllerData.xrController.grip.position\r\n : controllerData.xrController.pointer.position;\r\n controllerData.xrController.getWorldPointerRayToRef(controllerData.tmpRay, this._options.forceGripIfAvailable);\r\n } else if (controllerData.webXRCamera) {\r\n controllerGlobalPosition = controllerData.webXRCamera.position;\r\n controllerData.webXRCamera.getForwardRayToRef(controllerData.tmpRay);\r\n } else {\r\n continue;\r\n }\r\n\r\n if (this._options.maxPointerDistance) {\r\n controllerData.tmpRay.length = this._options.maxPointerDistance;\r\n }\r\n // update pointerX and pointerY of the scene. Only if the flag is set to true!\r\n if (!this._options.disableScenePointerVectorUpdate && controllerGlobalPosition) {\r\n const scene = this._xrSessionManager.scene;\r\n const camera = this._options.xrInput.xrCamera;\r\n if (camera) {\r\n camera.viewport.toGlobalToRef(scene.getEngine().getRenderWidth() / camera.rigCameras.length, scene.getEngine().getRenderHeight(), this._viewportRef);\r\n Vector3.ProjectToRef(controllerGlobalPosition, this._identityMatrix, camera.getTransformationMatrix(), this._viewportRef, this._screenCoordinatesRef);\r\n // stay safe\r\n if (\r\n typeof this._screenCoordinatesRef.x === \"number\" &&\r\n typeof this._screenCoordinatesRef.y === \"number\" &&\r\n !isNaN(this._screenCoordinatesRef.x) &&\r\n !isNaN(this._screenCoordinatesRef.y) &&\r\n this._screenCoordinatesRef.x !== Infinity &&\r\n this._screenCoordinatesRef.y !== Infinity\r\n ) {\r\n scene.pointerX = this._screenCoordinatesRef.x;\r\n scene.pointerY = this._screenCoordinatesRef.y;\r\n\r\n controllerData.screenCoordinates = {\r\n x: this._screenCoordinatesRef.x,\r\n y: this._screenCoordinatesRef.y,\r\n };\r\n }\r\n }\r\n }\r\n\r\n let utilityScenePick = null;\r\n if (this._utilityLayerScene) {\r\n utilityScenePick = this._utilityLayerScene.pickWithRay(controllerData.tmpRay, this._utilityLayerScene.pointerMovePredicate || this.raySelectionPredicate);\r\n }\r\n\r\n const originalScenePick = this._scene.pickWithRay(controllerData.tmpRay, this._scene.pointerMovePredicate || this.raySelectionPredicate);\r\n if (!utilityScenePick || !utilityScenePick.hit) {\r\n // No hit in utility scene\r\n controllerData.pick = originalScenePick;\r\n } else if (!originalScenePick || !originalScenePick.hit) {\r\n // No hit in original scene\r\n controllerData.pick = utilityScenePick;\r\n } else if (utilityScenePick.distance < originalScenePick.distance) {\r\n // Hit is closer in utility scene\r\n controllerData.pick = utilityScenePick;\r\n } else {\r\n // Hit is closer in original scene\r\n controllerData.pick = originalScenePick;\r\n }\r\n\r\n if (controllerData.pick && controllerData.xrController) {\r\n controllerData.pick.aimTransform = controllerData.xrController.pointer;\r\n controllerData.pick.gripTransform = controllerData.xrController.grip || null;\r\n controllerData.pick.originMesh = controllerData.xrController.pointer;\r\n controllerData.tmpRay.length = controllerData.pick.distance;\r\n }\r\n\r\n const pick = controllerData.pick;\r\n\r\n if (pick && pick.pickedPoint && pick.hit) {\r\n // Update laser state\r\n this._updatePointerDistance(controllerData.laserPointer, pick.distance);\r\n\r\n // Update cursor state\r\n controllerData.selectionMesh.position.copyFrom(pick.pickedPoint);\r\n controllerData.selectionMesh.scaling.x = Math.sqrt(pick.distance);\r\n controllerData.selectionMesh.scaling.y = Math.sqrt(pick.distance);\r\n controllerData.selectionMesh.scaling.z = Math.sqrt(pick.distance);\r\n\r\n // To avoid z-fighting\r\n const pickNormal = this._convertNormalToDirectionOfRay(pick.getNormal(true), controllerData.tmpRay);\r\n const deltaFighting = 0.001;\r\n controllerData.selectionMesh.position.copyFrom(pick.pickedPoint);\r\n if (pickNormal) {\r\n const axis1 = Vector3.Cross(Axis.Y, pickNormal);\r\n const axis2 = Vector3.Cross(pickNormal, axis1);\r\n Vector3.RotationFromAxisToRef(axis2, pickNormal, axis1, controllerData.selectionMesh.rotation);\r\n controllerData.selectionMesh.position.addInPlace(pickNormal.scale(deltaFighting));\r\n }\r\n controllerData.selectionMesh.isVisible = this.displaySelectionMesh;\r\n controllerData.meshUnderPointer = pick.pickedMesh;\r\n } else {\r\n controllerData.selectionMesh.isVisible = false;\r\n this._updatePointerDistance(controllerData.laserPointer, 1);\r\n controllerData.meshUnderPointer = null;\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 _attachGazeMode(xrController?: WebXRInputSource) {\r\n const controllerData = this._controllers[(xrController && xrController.uniqueId) || \"camera\"];\r\n // attached when touched, detaches when raised\r\n const timeToSelect = this._options.timeToSelect || 3000;\r\n const sceneToRenderTo = this._options.useUtilityLayer ? this._utilityLayerScene : this._scene;\r\n let oldPick = new PickingInfo();\r\n const discMesh = CreateTorus(\r\n \"selection\",\r\n {\r\n diameter: 0.0035 * 15,\r\n thickness: 0.0025 * 6,\r\n tessellation: 20,\r\n },\r\n sceneToRenderTo\r\n );\r\n discMesh.isVisible = false;\r\n discMesh.isPickable = false;\r\n discMesh.parent = controllerData.selectionMesh;\r\n let timer = 0;\r\n let downTriggered = false;\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 (!controllerData.pick) {\r\n return;\r\n }\r\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n controllerData.laserPointer.material!.alpha = 0;\r\n discMesh.isVisible = false;\r\n if (controllerData.pick.hit) {\r\n if (!this._pickingMoved(oldPick, controllerData.pick)) {\r\n if (timer > timeToSelect / 10) {\r\n discMesh.isVisible = true;\r\n }\r\n\r\n timer += this._scene.getEngine().getDeltaTime();\r\n if (timer >= timeToSelect) {\r\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n // this pointerdown event is not setting the controllerData.pointerDownTriggered to avoid a pointerUp event when this feature is detached\r\n downTriggered = true;\r\n // pointer up right after down, if disable on touch out\r\n if (this._options.disablePointerUpOnTouchOut) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n }\r\n discMesh.isVisible = false;\r\n } else {\r\n const scaleFactor = 1 - timer / timeToSelect;\r\n discMesh.scaling.set(scaleFactor, scaleFactor, scaleFactor);\r\n }\r\n } else {\r\n if (downTriggered) {\r\n if (!this._options.disablePointerUpOnTouchOut) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n }\r\n }\r\n downTriggered = false;\r\n timer = 0;\r\n }\r\n } else {\r\n downTriggered = false;\r\n timer = 0;\r\n }\r\n\r\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\r\n\r\n oldPick = controllerData.pick;\r\n });\r\n\r\n if (this._options.renderingGroupId !== undefined) {\r\n discMesh.renderingGroupId = this._options.renderingGroupId;\r\n }\r\n if (xrController) {\r\n xrController.onDisposeObservable.addOnce(() => {\r\n if (controllerData.pick && !this._options.disablePointerUpOnTouchOut && downTriggered) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n controllerData.finalPointerUpTriggered = true;\r\n }\r\n discMesh.dispose();\r\n });\r\n }\r\n }\r\n\r\n private _attachScreenRayMode(xrController: WebXRInputSource) {\r\n const controllerData = this._controllers[xrController.uniqueId];\r\n let downTriggered = false;\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 this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n if (!controllerData.pick || (this._options.disablePointerUpOnTouchOut && downTriggered)) {\r\n return;\r\n }\r\n if (!downTriggered) {\r\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n controllerData.pointerDownTriggered = true;\r\n downTriggered = true;\r\n if (this._options.disablePointerUpOnTouchOut) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n }\r\n } else {\r\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\r\n }\r\n });\r\n xrController.onDisposeObservable.addOnce(() => {\r\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n this._xrSessionManager.runInXRFrame(() => {\r\n if (controllerData.pick && !controllerData.finalPointerUpTriggered && downTriggered && !this._options.disablePointerUpOnTouchOut) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n controllerData.finalPointerUpTriggered = true;\r\n }\r\n });\r\n });\r\n }\r\n\r\n private _attachTrackedPointerRayMode(xrController: WebXRInputSource) {\r\n const controllerData = this._controllers[xrController.uniqueId];\r\n if (this._options.forceGazeMode) {\r\n return this._attachGazeMode(xrController);\r\n }\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 (<StandardMaterial>controllerData.laserPointer.material).disableLighting = this.disablePointerLighting;\r\n (<StandardMaterial>controllerData.selectionMesh.material).disableLighting = this.disableSelectionMeshLighting;\r\n\r\n if (controllerData.pick) {\r\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\r\n }\r\n });\r\n if (xrController.inputSource.gamepad) {\r\n const init = (motionController: WebXRAbstractMotionController) => {\r\n if (this._options.overrideButtonId) {\r\n controllerData.selectionComponent = motionController.getComponent(this._options.overrideButtonId);\r\n }\r\n if (!controllerData.selectionComponent) {\r\n controllerData.selectionComponent = motionController.getMainComponent();\r\n }\r\n\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 if (controllerData.pick) {\r\n if (this._options.enablePointerSelectionOnAllControllers || xrController.uniqueId === this._attachedController) {\r\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n if (pressed) {\r\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n controllerData.pointerDownTriggered = true;\r\n (<StandardMaterial>controllerData.selectionMesh.material).emissiveColor = this.selectionMeshPickedColor;\r\n (<StandardMaterial>controllerData.laserPointer.material).emissiveColor = this.laserPointerPickedColor;\r\n } else {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n (<StandardMaterial>controllerData.selectionMesh.material).emissiveColor = this.selectionMeshDefaultColor;\r\n (<StandardMaterial>controllerData.laserPointer.material).emissiveColor = this.laserPointerDefaultColor;\r\n }\r\n }\r\n } else {\r\n if (pressed && !this._options.enablePointerSelectionOnAllControllers && !this._options.disableSwitchOnClick) {\r\n // force a pointer up if switching controllers\r\n // get the controller that was attached before\r\n const prevController = this._controllers[this._attachedController];\r\n if (prevController && prevController.pointerDownTriggered && !prevController.finalPointerUpTriggered) {\r\n this._augmentPointerInit(pointerEventInit, prevController.id, prevController.screenCoordinates);\r\n this._scene.simulatePointerUp(new PickingInfo(), {\r\n pointerId: prevController.id,\r\n pointerType: \"xr\",\r\n });\r\n prevController.finalPointerUpTriggered = true;\r\n }\r\n this._attachedController = xrController.uniqueId;\r\n }\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 this._xrSessionManager.onXRFrameObservable.addOnce(() => {\r\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick) {\r\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\r\n controllerData.pointerDownTriggered = true;\r\n (<StandardMaterial>controllerData.selectionMesh.material).emissiveColor = this.selectionMeshPickedColor;\r\n (<StandardMaterial>controllerData.laserPointer.material).emissiveColor = this.laserPointerPickedColor;\r\n }\r\n });\r\n };\r\n\r\n const selectEndListener = (event: XRInputSourceEvent) => {\r\n this._xrSessionManager.onXRFrameObservable.addOnce(() => {\r\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick) {\r\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\r\n (<StandardMaterial>controllerData.selectionMesh.material).emissiveColor = this.selectionMeshDefaultColor;\r\n (<StandardMaterial>controllerData.laserPointer.material).emissiveColor = this.laserPointerDefaultColor;\r\n }\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 _convertNormalToDirectionOfRay(normal: Nullable<Vector3>, ray: Ray) {\r\n if (normal) {\r\n const angle = Math.acos(Vector3.Dot(normal, ray.direction));\r\n if (angle < Math.PI / 2) {\r\n normal.scaleInPlace(-1);\r\n }\r\n }\r\n return normal;\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.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 const keys = Object.keys(controllerData.eventListeners);\r\n for (const eventName of keys) {\r\n const func = controllerData.eventListeners && controllerData.eventListeners[eventName as XREventType];\r\n if (func) {\r\n // For future reference - this is an issue in the WebXR typings.\r\n this._xrSessionManager.session.removeEventListener(eventName as XREventType, func as any);\r\n }\r\n }\r\n }\r\n\r\n if (!controllerData.finalPointerUpTriggered && controllerData.pointerDownTriggered) {\r\n // Stay safe and fire a pointerup, in case it wasn't already triggered\r\n const pointerEventInit: PointerEventInit = {\r\n pointerId: controllerData.id,\r\n pointerType: \"xr\",\r\n };\r\n this._xrSessionManager.runInXRFrame(() => {\r\n this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);\r\n this._scene.simulatePointerUp(controllerData.pick || new PickingInfo(), pointerEventInit);\r\n controllerData.finalPointerUpTriggered = true;\r\n });\r\n }\r\n this._xrSessionManager.scene.onBeforeRenderObservable.addOnce(() => {\r\n try {\r\n controllerData.selectionMesh.dispose();\r\n controllerData.laserPointer.dispose();\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 } catch (e) {\r\n Tools.Warn(\"controller already detached.\");\r\n }\r\n });\r\n }\r\n\r\n private _generateNewMeshPair(meshParent: Node) {\r\n const sceneToRenderTo = this._options.useUtilityLayer ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene : this._scene;\r\n const laserPointer = this._options.customLasterPointerMeshGenerator\r\n ? this._options.customLasterPointerMeshGenerator()\r\n : CreateCylinder(\r\n \"laserPointer\",\r\n {\r\n height: 1,\r\n diameterTop: 0.0002,\r\n diameterBottom: 0.004,\r\n tessellation: 20,\r\n subdivisions: 1,\r\n },\r\n sceneToRenderTo\r\n );\r\n laserPointer.parent = meshParent;\r\n const laserPointerMaterial = new StandardMaterial(\"laserPointerMat\", sceneToRenderTo);\r\n laserPointerMaterial.emissiveColor = this.laserPointerDefaultColor;\r\n laserPointerMaterial.alpha = 0.7;\r\n laserPointer.material = laserPointerMaterial;\r\n laserPointer.rotation.x = Math.PI / 2;\r\n this._updatePointerDistance(laserPointer, 1);\r\n laserPointer.isPickable = false;\r\n laserPointer.isVisible = false;\r\n\r\n // Create a gaze tracker for the XR controller\r\n const selectionMesh = this._options.customSelectionMeshGenerator\r\n ? this._options.customSelectionMeshGenerator()\r\n : CreateTorus(\r\n \"gazeTracker\",\r\n {\r\n diameter: 0.0035 * 3,\r\n thickness: 0.0025 * 3,\r\n tessellation: 20,\r\n },\r\n sceneToRenderTo\r\n );\r\n selectionMesh.bakeCurrentTransformIntoVertices();\r\n selectionMesh.isPickable = false;\r\n selectionMesh.isVisible = false;\r\n const 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 if (this._options.renderingGroupId !== undefined) {\r\n laserPointer.renderingGroupId = this._options.renderingGroupId;\r\n selectionMesh.renderingGroupId = this._options.renderingGroupId;\r\n }\r\n\r\n return {\r\n laserPointer,\r\n selectionMesh,\r\n };\r\n }\r\n\r\n private _pickingMoved(oldPick: PickingInfo, newPick: PickingInfo) {\r\n if (!oldPick.hit || !newPick.hit) {\r\n return true;\r\n }\r\n if (!oldPick.pickedMesh || !oldPick.pickedPoint || !newPick.pickedMesh || !newPick.pickedPoint) {\r\n return true;\r\n }\r\n if (oldPick.pickedMesh !== newPick.pickedMesh) {\r\n return true;\r\n }\r\n oldPick.pickedPoint?.subtractToRef(newPick.pickedPoint, this._tmpVectorForPickCompare);\r\n this._tmpVectorForPickCompare.set(Math.abs(this._tmpVectorForPickCompare.x), Math.abs(this._tmpVectorForPickCompare.y), Math.abs(this._tmpVectorForPickCompare.z));\r\n const delta = (this._options.gazeModePointerMovedFactor || 1) * 0.01 * newPick.distance;\r\n const length = this._tmpVectorForPickCompare.length();\r\n if (length > delta) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n private _updatePointerDistance(_laserPointer: AbstractMesh, distance: number = 100) {\r\n _laserPointer.scaling.y = distance;\r\n // a bit of distance from the controller\r\n if (this._scene.useRightHandedSystem) {\r\n distance *= -1;\r\n }\r\n _laserPointer.position.z = distance / 2 + 0.05;\r\n }\r\n\r\n private _augmentPointerInit(pointerEventInit: PointerEventInit, id: number, screenCoordinates?: { x: number; y: number }): void {\r\n pointerEventInit.pointerId = id;\r\n pointerEventInit.pointerType = \"xr\";\r\n if (screenCoordinates) {\r\n pointerEventInit.screenX = screenCoordinates.x;\r\n pointerEventInit.screenY = screenCoordinates.y;\r\n }\r\n }\r\n\r\n /** @internal */\r\n public get lasterPointerDefaultColor(): Color3 {\r\n // here due to a typo\r\n return this.laserPointerDefaultColor;\r\n }\r\n}\r\n\r\n//register the plugin\r\nWebXRFeaturesManager.AddWebXRFeature(\r\n WebXRControllerPointerSelection.Name,\r\n (xrSessionManager, options) => {\r\n return () => new WebXRControllerPointerSelection(xrSessionManager, options);\r\n },\r\n WebXRControllerPointerSelection.Version,\r\n true\r\n);\r\n"]}
|
|
@@ -300,6 +300,19 @@ export declare class WebXRMotionControllerTeleportation extends WebXRAbstractFea
|
|
|
300
300
|
private _findClosestSnapPointWithRadius;
|
|
301
301
|
private _setTargetMeshPosition;
|
|
302
302
|
private _setTargetMeshVisibility;
|
|
303
|
+
/**
|
|
304
|
+
* Computes the parabolic ray origin and direction for teleportation.
|
|
305
|
+
* The effective radius scales with the horizontal component of the controller direction,
|
|
306
|
+
* so pointing more vertically results in shorter landing distances.
|
|
307
|
+
* Note: the actual landing distance also depends on controller height above the floor;
|
|
308
|
+
* `parabolicCheckRadius` controls the forward offset, not a strict max ground distance.
|
|
309
|
+
* Modifies the ray in place — the new origin serves as both the raycast start
|
|
310
|
+
* and the Bezier control point for the visual arc.
|
|
311
|
+
* @param ray - The controller ray (origin at controller, direction is forward). Modified in place.
|
|
312
|
+
* @param tmpVector - Pre-allocated temporary vector for computation. Modified in place.
|
|
313
|
+
* @returns true if the parabolic ray was computed, false if direction is too vertical
|
|
314
|
+
*/
|
|
315
|
+
private _buildParabolicRay;
|
|
303
316
|
private _disposeBezierCurve;
|
|
304
317
|
private _colorArray;
|
|
305
318
|
private _showParabolicPath;
|
|
@@ -573,17 +573,7 @@ export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {
|
|
|
573
573
|
}
|
|
574
574
|
}
|
|
575
575
|
// straight ray is still the main ray, but disabling the straight line will force parabolic line.
|
|
576
|
-
if (this.parabolicRayEnabled && !hitPossible) {
|
|
577
|
-
// radius compensation according to pointer rotation around X
|
|
578
|
-
const xRotation = controllerData.xrController.pointer.rotationQuaternion.toEulerAngles().x;
|
|
579
|
-
const compensation = 1 + (Math.PI / 2 - Math.abs(xRotation));
|
|
580
|
-
// check parabolic ray
|
|
581
|
-
const radius = this.parabolicCheckRadius * compensation;
|
|
582
|
-
this._tmpRay.origin.addToRef(this._tmpRay.direction.scale(radius * 2), this._tmpVector);
|
|
583
|
-
this._tmpVector.y = this._tmpRay.origin.y;
|
|
584
|
-
this._tmpRay.origin.addInPlace(this._tmpRay.direction.scale(radius));
|
|
585
|
-
this._tmpVector.subtractToRef(this._tmpRay.origin, this._tmpRay.direction);
|
|
586
|
-
this._tmpRay.direction.normalize();
|
|
576
|
+
if (this.parabolicRayEnabled && !hitPossible && this._buildParabolicRay(this._tmpRay, this._tmpVector)) {
|
|
587
577
|
const pick = scene.pickWithRay(this._tmpRay, (o) => {
|
|
588
578
|
if (this._options.blockerMeshesPredicate && this._options.blockerMeshesPredicate(o)) {
|
|
589
579
|
return true;
|
|
@@ -800,6 +790,43 @@ export class WebXRMotionControllerTeleportation extends WebXRAbstractFeature {
|
|
|
800
790
|
}
|
|
801
791
|
}
|
|
802
792
|
}
|
|
793
|
+
/**
|
|
794
|
+
* Computes the parabolic ray origin and direction for teleportation.
|
|
795
|
+
* The effective radius scales with the horizontal component of the controller direction,
|
|
796
|
+
* so pointing more vertically results in shorter landing distances.
|
|
797
|
+
* Note: the actual landing distance also depends on controller height above the floor;
|
|
798
|
+
* `parabolicCheckRadius` controls the forward offset, not a strict max ground distance.
|
|
799
|
+
* Modifies the ray in place — the new origin serves as both the raycast start
|
|
800
|
+
* and the Bezier control point for the visual arc.
|
|
801
|
+
* @param ray - The controller ray (origin at controller, direction is forward). Modified in place.
|
|
802
|
+
* @param tmpVector - Pre-allocated temporary vector for computation. Modified in place.
|
|
803
|
+
* @returns true if the parabolic ray was computed, false if direction is too vertical
|
|
804
|
+
*/
|
|
805
|
+
_buildParabolicRay(ray, tmpVector) {
|
|
806
|
+
const dir = ray.direction;
|
|
807
|
+
const horizontalLengthSq = dir.x * dir.x + dir.z * dir.z;
|
|
808
|
+
const horizontalLength = Math.sqrt(horizontalLengthSq);
|
|
809
|
+
// Skip if pointing almost straight up or down — no meaningful horizontal reach
|
|
810
|
+
if (horizontalLength < 0.01) {
|
|
811
|
+
return false;
|
|
812
|
+
}
|
|
813
|
+
// Effective radius scales with horizontal component of direction.
|
|
814
|
+
// Pointing horizontally (horizontalLength ~ 1) gives full reach.
|
|
815
|
+
// Pointing up (horizontalLength ~ 0) gives minimal reach.
|
|
816
|
+
const effectiveRadius = this.parabolicCheckRadius * horizontalLength;
|
|
817
|
+
// Place "air point" at effectiveRadius forward in controller direction, then flatten Y.
|
|
818
|
+
// This represents the far ground-level target the ray angles toward.
|
|
819
|
+
dir.scaleToRef(effectiveRadius, tmpVector);
|
|
820
|
+
tmpVector.addInPlace(ray.origin);
|
|
821
|
+
tmpVector.y = ray.origin.y;
|
|
822
|
+
// Move ray origin forward by half the effective radius along controller direction.
|
|
823
|
+
// This elevated midpoint serves as both the raycast start and the Bezier control point.
|
|
824
|
+
dir.scaleAndAddToRef(effectiveRadius * 0.5, ray.origin);
|
|
825
|
+
// Direction from the new origin toward the air point (angled downward)
|
|
826
|
+
tmpVector.subtractToRef(ray.origin, ray.direction);
|
|
827
|
+
ray.direction.normalize();
|
|
828
|
+
return true;
|
|
829
|
+
}
|
|
803
830
|
_disposeBezierCurve() {
|
|
804
831
|
if (this._quadraticBezierCurve) {
|
|
805
832
|
this._quadraticBezierCurve.dispose();
|