@babylonjs/core 8.52.0 → 8.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/Animations/animatorAvatar.d.ts +31 -16
  2. package/Animations/animatorAvatar.js +138 -86
  3. package/Animations/animatorAvatar.js.map +1 -1
  4. package/AudioV2/abstractAudio/abstractSound.js +3 -4
  5. package/AudioV2/abstractAudio/abstractSound.js.map +1 -1
  6. package/AudioV2/abstractAudio/audioBus.js +3 -0
  7. package/AudioV2/abstractAudio/audioBus.js.map +1 -1
  8. package/AudioV2/abstractAudio/streamingSoundInstance.d.ts +1 -1
  9. package/AudioV2/abstractAudio/streamingSoundInstance.js +2 -2
  10. package/AudioV2/abstractAudio/streamingSoundInstance.js.map +1 -1
  11. package/AudioV2/webAudio/components/spatialWebAudioUpdaterComponent.d.ts +4 -1
  12. package/AudioV2/webAudio/components/spatialWebAudioUpdaterComponent.js +5 -2
  13. package/AudioV2/webAudio/components/spatialWebAudioUpdaterComponent.js.map +1 -1
  14. package/AudioV2/webAudio/webAudioStaticSound.js +3 -3
  15. package/AudioV2/webAudio/webAudioStaticSound.js.map +1 -1
  16. package/AudioV2/webAudio/webAudioStreamingSound.js +2 -4
  17. package/AudioV2/webAudio/webAudioStreamingSound.js.map +1 -1
  18. package/Behaviors/Meshes/pointerDragBehavior.d.ts +6 -0
  19. package/Behaviors/Meshes/pointerDragBehavior.js +4 -0
  20. package/Behaviors/Meshes/pointerDragBehavior.js.map +1 -1
  21. package/Cameras/Inputs/geospatialCameraKeyboardInput.js +6 -3
  22. package/Cameras/Inputs/geospatialCameraKeyboardInput.js.map +1 -1
  23. package/Cameras/geospatialCamera.d.ts +4 -2
  24. package/Cameras/geospatialCamera.js +10 -8
  25. package/Cameras/geospatialCamera.js.map +1 -1
  26. package/Cameras/geospatialCameraMovement.d.ts +11 -1
  27. package/Cameras/geospatialCameraMovement.js +26 -6
  28. package/Cameras/geospatialCameraMovement.js.map +1 -1
  29. package/Debug/physicsViewer.d.ts +1 -0
  30. package/Debug/physicsViewer.js +1 -0
  31. package/Debug/physicsViewer.js.map +1 -1
  32. package/Engines/WebGPU/webgpuBufferManager.js +3 -1
  33. package/Engines/WebGPU/webgpuBufferManager.js.map +1 -1
  34. package/Engines/abstractEngine.js +2 -2
  35. package/Engines/abstractEngine.js.map +1 -1
  36. package/Engines/nullEngine.js +4 -0
  37. package/Engines/nullEngine.js.map +1 -1
  38. package/Engines/webgpuEngine.js +2 -2
  39. package/Engines/webgpuEngine.js.map +1 -1
  40. package/FrameGraph/frameGraph.d.ts +21 -1
  41. package/FrameGraph/frameGraph.js +49 -0
  42. package/FrameGraph/frameGraph.js.map +1 -1
  43. package/FrameGraph/frameGraphUtils.d.ts +1 -2
  44. package/FrameGraph/frameGraphUtils.js +2 -27
  45. package/FrameGraph/frameGraphUtils.js.map +1 -1
  46. package/Gizmos/axisDragGizmo.d.ts +1 -1
  47. package/Gizmos/axisDragGizmo.js +13 -5
  48. package/Gizmos/axisDragGizmo.js.map +1 -1
  49. package/Gizmos/gizmo.js +8 -2
  50. package/Gizmos/gizmo.js.map +1 -1
  51. package/Gizmos/planeDragGizmo.js +10 -3
  52. package/Gizmos/planeDragGizmo.js.map +1 -1
  53. package/Gizmos/planeRotationGizmo.js +10 -0
  54. package/Gizmos/planeRotationGizmo.js.map +1 -1
  55. package/Helpers/environmentHelper.js +7 -0
  56. package/Helpers/environmentHelper.js.map +1 -1
  57. package/Layers/highlightLayer.d.ts +14 -0
  58. package/Layers/highlightLayer.js +20 -0
  59. package/Layers/highlightLayer.js.map +1 -1
  60. package/Layers/selectionOutlineLayer.d.ts +1 -0
  61. package/Layers/selectionOutlineLayer.js +1 -0
  62. package/Layers/selectionOutlineLayer.js.map +1 -1
  63. package/Layers/thinEffectLayer.js +25 -1
  64. package/Layers/thinEffectLayer.js.map +1 -1
  65. package/Layers/thinHighlightLayer.d.ts +9 -0
  66. package/Layers/thinHighlightLayer.js +19 -3
  67. package/Layers/thinHighlightLayer.js.map +1 -1
  68. package/Lights/Clustered/clusteredLightContainer.js +10 -8
  69. package/Lights/Clustered/clusteredLightContainer.js.map +1 -1
  70. package/Loading/Plugins/babylonFileLoader.d.ts +2 -0
  71. package/Loading/Plugins/babylonFileLoader.js +2 -0
  72. package/Loading/Plugins/babylonFileLoader.js.map +1 -1
  73. package/Materials/Node/Blocks/Dual/depthSourceBlock.d.ts +1 -0
  74. package/Materials/Node/Blocks/Dual/depthSourceBlock.js +1 -0
  75. package/Materials/Node/Blocks/Dual/depthSourceBlock.js.map +1 -1
  76. package/Materials/Node/Blocks/Dual/sceneDepthBlock.d.ts +1 -0
  77. package/Materials/Node/Blocks/Dual/sceneDepthBlock.js +1 -0
  78. package/Materials/Node/Blocks/Dual/sceneDepthBlock.js.map +1 -1
  79. package/Materials/Node/Blocks/Teleport/teleportOutBlock.js +10 -4
  80. package/Materials/Node/Blocks/Teleport/teleportOutBlock.js.map +1 -1
  81. package/Materials/Textures/renderTargetTexture.js +6 -4
  82. package/Materials/Textures/renderTargetTexture.js.map +1 -1
  83. package/Materials/effect.functions.js +29 -21
  84. package/Materials/effect.functions.js.map +1 -1
  85. package/Meshes/thinInstanceMesh.d.ts +7 -3
  86. package/Meshes/thinInstanceMesh.js +15 -3
  87. package/Meshes/thinInstanceMesh.js.map +1 -1
  88. package/Misc/snapshotRenderingHelper.d.ts +5 -3
  89. package/Misc/snapshotRenderingHelper.js +9 -5
  90. package/Misc/snapshotRenderingHelper.js.map +1 -1
  91. package/Particles/EmitterTypes/coneParticleEmitter.js +3 -3
  92. package/Particles/EmitterTypes/coneParticleEmitter.js.map +1 -1
  93. package/Particles/EmitterTypes/sphereParticleEmitter.js +2 -2
  94. package/Particles/EmitterTypes/sphereParticleEmitter.js.map +1 -1
  95. package/Particles/Node/Blocks/index.d.ts +0 -2
  96. package/Particles/Node/Blocks/index.js +0 -2
  97. package/Particles/Node/Blocks/index.js.map +1 -1
  98. package/Particles/Node/Blocks/particleNumberMathBlock.js +16 -0
  99. package/Particles/Node/Blocks/particleNumberMathBlock.js.map +1 -1
  100. package/Particles/Node/Blocks/systemBlock.d.ts +0 -4
  101. package/Particles/Node/Blocks/systemBlock.js +1 -32
  102. package/Particles/Node/Blocks/systemBlock.js.map +1 -1
  103. package/Particles/Node/nodeParticleSystemSet.helper.js +2 -89
  104. package/Particles/Node/nodeParticleSystemSet.helper.js.map +1 -1
  105. package/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.d.ts +1 -0
  106. package/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.js +1 -0
  107. package/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.js.map +1 -1
  108. package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.d.ts +1 -0
  109. package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.js +1 -0
  110. package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.js.map +1 -1
  111. package/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.d.ts +6 -0
  112. package/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.js +8 -0
  113. package/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.js.map +1 -1
  114. package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.d.ts +1 -0
  115. package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.js +1 -0
  116. package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.js.map +1 -1
  117. package/PostProcesses/RenderPipeline/Pipelines/ssrRenderingPipeline.d.ts +6 -0
  118. package/PostProcesses/RenderPipeline/Pipelines/ssrRenderingPipeline.js +8 -0
  119. package/PostProcesses/RenderPipeline/Pipelines/ssrRenderingPipeline.js.map +1 -1
  120. package/PostProcesses/RenderPipeline/Pipelines/standardRenderingPipeline.d.ts +1 -0
  121. package/PostProcesses/RenderPipeline/Pipelines/standardRenderingPipeline.js +1 -0
  122. package/PostProcesses/RenderPipeline/Pipelines/standardRenderingPipeline.js.map +1 -1
  123. package/PostProcesses/screenSpaceReflectionPostProcess.d.ts +1 -0
  124. package/PostProcesses/screenSpaceReflectionPostProcess.js +1 -0
  125. package/PostProcesses/screenSpaceReflectionPostProcess.js.map +1 -1
  126. package/Rendering/GlobalIllumination/giRSMManager.d.ts +1 -0
  127. package/Rendering/GlobalIllumination/giRSMManager.js +1 -0
  128. package/Rendering/GlobalIllumination/giRSMManager.js.map +1 -1
  129. package/Rendering/IBLShadows/iblShadowsAccumulationPass.js +7 -3
  130. package/Rendering/IBLShadows/iblShadowsAccumulationPass.js.map +1 -1
  131. package/Rendering/IBLShadows/iblShadowsSpatialBlurPass.js +3 -1
  132. package/Rendering/IBLShadows/iblShadowsSpatialBlurPass.js.map +1 -1
  133. package/Rendering/IBLShadows/iblShadowsVoxelTracingPass.js +3 -1
  134. package/Rendering/IBLShadows/iblShadowsVoxelTracingPass.js.map +1 -1
  135. package/Rendering/geometryBufferRenderer.js +3 -0
  136. package/Rendering/geometryBufferRenderer.js.map +1 -1
  137. package/Rendering/prePassRenderer.d.ts +1 -0
  138. package/Rendering/prePassRenderer.js +1 -0
  139. package/Rendering/prePassRenderer.js.map +1 -1
  140. package/Shaders/gpuUpdateParticles.vertex.js +1 -1
  141. package/Shaders/gpuUpdateParticles.vertex.js.map +1 -1
  142. package/ShadersWGSL/ShadersInclude/depthPrePass.js +4 -1
  143. package/ShadersWGSL/ShadersInclude/depthPrePass.js.map +1 -1
  144. package/ShadersWGSL/background.fragment.js +1 -1
  145. package/ShadersWGSL/background.fragment.js.map +1 -1
  146. package/ShadersWGSL/default.fragment.js +1 -1
  147. package/ShadersWGSL/default.fragment.js.map +1 -1
  148. package/ShadersWGSL/gpuUpdateParticles.compute.js +1 -1
  149. package/ShadersWGSL/gpuUpdateParticles.compute.js.map +1 -1
  150. package/XR/features/WebXRControllerPhysics.d.ts +1 -0
  151. package/XR/features/WebXRControllerPhysics.js +1 -0
  152. package/XR/features/WebXRControllerPhysics.js.map +1 -1
  153. package/XR/features/WebXRHandTracking.d.ts +1 -0
  154. package/XR/features/WebXRHandTracking.js +1 -0
  155. package/XR/features/WebXRHandTracking.js.map +1 -1
  156. package/package.json +1 -1
  157. package/scene.js +19 -1
  158. package/scene.js.map +1 -1
  159. package/Particles/Node/Blocks/Update/updateRemapBlock.d.ts +0 -39
  160. package/Particles/Node/Blocks/Update/updateRemapBlock.js +0 -93
  161. package/Particles/Node/Blocks/Update/updateRemapBlock.js.map +0 -1
  162. package/Particles/Node/Blocks/particleFresnelBlock.d.ts +0 -34
  163. package/Particles/Node/Blocks/particleFresnelBlock.js +0 -74
  164. package/Particles/Node/Blocks/particleFresnelBlock.js.map +0 -1
@@ -153,9 +153,12 @@ export class GeospatialCameraKeyboardInput {
153
153
  camera.movement.handleZoom(-this.zoomSensitivity, false);
154
154
  }
155
155
  else {
156
- // Call into movement class handleDrag so that behavior matches that of pointer input, simulating drag from center of screen
157
- const centerX = this._engine.getRenderWidth() / 2;
158
- const centerY = this._engine.getRenderHeight() / 2;
156
+ // Call into movement class handleDrag so that behavior matches that of pointer input, simulating drag from center of screen.
157
+ // getRenderWidth/Height return render buffer pixels (scaled by hardwareScalingLevel relative to CSS pixels),
158
+ // but the picking logic (scene.pick via CreatePickingRayToRef) expects CSS pixels (it divides by hardwareScalingLevel internally).
159
+ const hardwareScaling = this._engine.getHardwareScalingLevel();
160
+ const centerX = (this._engine.getRenderWidth() / 2) * hardwareScaling;
161
+ const centerY = (this._engine.getRenderHeight() / 2) * hardwareScaling;
159
162
  camera.movement.startDrag(centerX, centerY);
160
163
  if (this.keysLeft.indexOf(keyCode) !== -1) {
161
164
  camera.movement.handleDrag(centerX + this.panSensitivity, centerY);
@@ -1 +1 @@
1
- {"version":3,"file":"geospatialCameraKeyboardInput.js","sourceRoot":"","sources":["../../../../../dev/core/src/Cameras/Inputs/geospatialCameraKeyboardInput.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport type { Observer } from \"../../Misc/observable\";\r\nimport type { Scene } from \"../../scene\";\r\nimport type { GeospatialCamera } from \"../geospatialCamera\";\r\nimport type { ICameraInput } from \"../cameraInputsManager\";\r\nimport { CameraInputTypes } from \"../cameraInputsManager\";\r\nimport type { KeyboardInfo } from \"../../Events/keyboardEvents\";\r\nimport { KeyboardEventTypes } from \"../../Events/keyboardEvents\";\r\nimport { Tools } from \"../../Misc/tools\";\r\nimport type { AbstractEngine } from \"../../Engines/abstractEngine\";\r\n\r\n/**\r\n * Manage the keyboard inputs to control the movement of a geospatial camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class GeospatialCameraKeyboardInput implements ICameraInput<GeospatialCamera> {\r\n /**\r\n * Defines the camera the input is attached to.\r\n */\r\n public camera: GeospatialCamera;\r\n\r\n /**\r\n * Defines the list of key codes associated with the up action (pan up)\r\n */\r\n @serialize()\r\n public keysUp = [38];\r\n\r\n /**\r\n * Defines the list of key codes associated with the down action (pan down)\r\n */\r\n @serialize()\r\n public keysDown = [40];\r\n\r\n /**\r\n * Defines the list of key codes associated with the left action (pan left)\r\n */\r\n @serialize()\r\n public keysLeft = [37];\r\n\r\n /**\r\n * Defines the list of key codes associated with the right action (pan right)\r\n */\r\n @serialize()\r\n public keysRight = [39];\r\n\r\n /**\r\n * Defines the list of key codes associated with zoom in (+ or =)\r\n */\r\n @serialize()\r\n public keysZoomIn = [187, 107]; // 187 = + key, 107 = numpad +\r\n\r\n /**\r\n * Defines the list of key codes associated with zoom out (-)\r\n */\r\n @serialize()\r\n public keysZoomOut = [189, 109]; // 189 = - key, 109 = numpad -\r\n\r\n /**\r\n * Defines the rotation sensitivity of the inputs.\r\n * (How many pixels of pointer input to apply per keypress, before rotation speed factor is applied by movement class)\r\n */\r\n @serialize()\r\n public rotationSensitivity = 1.0;\r\n\r\n /**\r\n * Defines the panning sensitivity of the inputs.\r\n * (How many pixels of pointer input to apply per keypress, before pan speed factor is applied by movement class)\r\n */\r\n @serialize()\r\n public panSensitivity: number = 1.0;\r\n\r\n /**\r\n * Defines the zooming sensitivity of the inputs.\r\n * (How many pixels of pointer input to apply per keypress, before zoom speed factor is applied by movement class)\r\n */\r\n @serialize()\r\n public zoomSensitivity: number = 1.0;\r\n\r\n private _keys = new Array<number>();\r\n private _ctrlPressed: boolean;\r\n private _onCanvasBlurObserver: Nullable<Observer<AbstractEngine>>;\r\n private _onKeyboardObserver: Nullable<Observer<KeyboardInfo>>;\r\n private _engine: AbstractEngine;\r\n private _scene: Scene;\r\n\r\n /**\r\n * Attach the input controls to a specific dom element to get the input from.\r\n * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n */\r\n public attachControl(noPreventDefault?: boolean): void {\r\n // was there a second variable defined?\r\n noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n\r\n if (this._onCanvasBlurObserver) {\r\n return;\r\n }\r\n\r\n this._scene = this.camera.getScene();\r\n this._engine = this._scene.getEngine();\r\n\r\n this._onCanvasBlurObserver = this._engine.onCanvasBlurObservable.add(() => {\r\n this._keys.length = 0;\r\n });\r\n\r\n this._onKeyboardObserver = this._scene.onKeyboardObservable.add((info) => {\r\n const evt = info.event;\r\n if (!evt.metaKey) {\r\n if (info.type === KeyboardEventTypes.KEYDOWN) {\r\n this._ctrlPressed = evt.ctrlKey;\r\n\r\n if (\r\n this.keysUp.indexOf(evt.keyCode) !== -1 ||\r\n this.keysDown.indexOf(evt.keyCode) !== -1 ||\r\n this.keysLeft.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRight.indexOf(evt.keyCode) !== -1 ||\r\n this.keysZoomIn.indexOf(evt.keyCode) !== -1 ||\r\n this.keysZoomOut.indexOf(evt.keyCode) !== -1\r\n ) {\r\n const index = this._keys.indexOf(evt.keyCode);\r\n\r\n if (index === -1) {\r\n this._keys.push(evt.keyCode);\r\n }\r\n\r\n if (evt.preventDefault) {\r\n if (!noPreventDefault) {\r\n evt.preventDefault();\r\n }\r\n }\r\n }\r\n } else {\r\n if (\r\n this.keysUp.indexOf(evt.keyCode) !== -1 ||\r\n this.keysDown.indexOf(evt.keyCode) !== -1 ||\r\n this.keysLeft.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRight.indexOf(evt.keyCode) !== -1 ||\r\n this.keysZoomIn.indexOf(evt.keyCode) !== -1 ||\r\n this.keysZoomOut.indexOf(evt.keyCode) !== -1\r\n ) {\r\n const index = this._keys.indexOf(evt.keyCode);\r\n\r\n if (index >= 0) {\r\n this._keys.splice(index, 1);\r\n }\r\n\r\n if (evt.preventDefault) {\r\n if (!noPreventDefault) {\r\n evt.preventDefault();\r\n }\r\n }\r\n }\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Detach the current controls from the specified dom element.\r\n */\r\n public detachControl(): void {\r\n if (this._scene) {\r\n this._onKeyboardObserver?.remove();\r\n this._onKeyboardObserver = null;\r\n this._onCanvasBlurObserver?.remove();\r\n this._onCanvasBlurObserver = null;\r\n }\r\n\r\n this._keys.length = 0;\r\n }\r\n\r\n /**\r\n * Update the current camera state depending on the inputs that have been used this frame.\r\n * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n */\r\n public checkInputs(): void {\r\n if (this._onKeyboardObserver) {\r\n const camera = this.camera;\r\n\r\n for (let index = 0; index < this._keys.length; index++) {\r\n const keyCode = this._keys[index];\r\n if (this._ctrlPressed) {\r\n // Rotation\r\n if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n camera.movement.rotationAccumulatedPixels.y -= this.rotationSensitivity;\r\n } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n camera.movement.rotationAccumulatedPixels.y += this.rotationSensitivity;\r\n } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n camera.movement.rotationAccumulatedPixels.x -= this.rotationSensitivity;\r\n } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n camera.movement.rotationAccumulatedPixels.x += this.rotationSensitivity;\r\n }\r\n } else {\r\n // Zoom\r\n if (this.keysZoomIn.indexOf(keyCode) !== -1) {\r\n camera.movement.handleZoom(this.zoomSensitivity, false);\r\n } else if (this.keysZoomOut.indexOf(keyCode) !== -1) {\r\n camera.movement.handleZoom(-this.zoomSensitivity, false);\r\n } else {\r\n // Call into movement class handleDrag so that behavior matches that of pointer input, simulating drag from center of screen\r\n const centerX = this._engine.getRenderWidth() / 2;\r\n const centerY = this._engine.getRenderHeight() / 2;\r\n camera.movement.startDrag(centerX, centerY);\r\n if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n camera.movement.handleDrag(centerX + this.panSensitivity, centerY);\r\n } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n camera.movement.handleDrag(centerX - this.panSensitivity, centerY);\r\n } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n camera.movement.handleDrag(centerX, centerY + this.panSensitivity);\r\n } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n camera.movement.handleDrag(centerX, centerY - this.panSensitivity);\r\n }\r\n camera.movement.stopDrag();\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Gets the class name of the current input.\r\n * @returns the class name\r\n */\r\n public getClassName(): string {\r\n return \"GeospatialCameraKeyboardInput\";\r\n }\r\n\r\n /**\r\n * Get the friendly name associated with the input class.\r\n * @returns the input friendly name\r\n */\r\n public getSimpleName(): string {\r\n return \"keyboard\";\r\n }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"GeospatialCameraKeyboardInput\"] = GeospatialCameraKeyboardInput;\r\n"]}
1
+ {"version":3,"file":"geospatialCameraKeyboardInput.js","sourceRoot":"","sources":["../../../../../dev/core/src/Cameras/Inputs/geospatialCameraKeyboardInput.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAKlD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAGzC;;;GAGG;AACH,MAAM,OAAO,6BAA6B;IAA1C;QAMI;;WAEG;QAEI,WAAM,GAAG,CAAC,EAAE,CAAC,CAAC;QAErB;;WAEG;QAEI,aAAQ,GAAG,CAAC,EAAE,CAAC,CAAC;QAEvB;;WAEG;QAEI,aAAQ,GAAG,CAAC,EAAE,CAAC,CAAC;QAEvB;;WAEG;QAEI,cAAS,GAAG,CAAC,EAAE,CAAC,CAAC;QAExB;;WAEG;QAEI,eAAU,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,8BAA8B;QAE9D;;WAEG;QAEI,gBAAW,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,8BAA8B;QAE/D;;;WAGG;QAEI,wBAAmB,GAAG,GAAG,CAAC;QAEjC;;;WAGG;QAEI,mBAAc,GAAW,GAAG,CAAC;QAEpC;;;WAGG;QAEI,oBAAe,GAAW,GAAG,CAAC;QAE7B,UAAK,GAAG,IAAI,KAAK,EAAU,CAAC;IA8JxC,CAAC;IAvJG;;;OAGG;IACI,aAAa,CAAC,gBAA0B;QAC3C,uCAAuC;QACvC,gBAAgB,GAAG,KAAK,CAAC,gCAAgC,CAAC,SAAS,CAAC,CAAC;QAErE,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC7B,OAAO;QACX,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QAEvC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,EAAE;YACtE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACrE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;gBACf,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB,CAAC,OAAO,EAAE,CAAC;oBAC3C,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC;oBAEhC,IACI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;wBACvC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;wBACzC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;wBACzC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;wBAC1C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;wBAC3C,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAC9C,CAAC;wBACC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;wBAE9C,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;4BACf,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;wBACjC,CAAC;wBAED,IAAI,GAAG,CAAC,cAAc,EAAE,CAAC;4BACrB,IAAI,CAAC,gBAAgB,EAAE,CAAC;gCACpB,GAAG,CAAC,cAAc,EAAE,CAAC;4BACzB,CAAC;wBACL,CAAC;oBACL,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,IACI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;wBACvC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;wBACzC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;wBACzC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;wBAC1C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;wBAC3C,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAC9C,CAAC;wBACC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;wBAE9C,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;4BACb,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;wBAChC,CAAC;wBAED,IAAI,GAAG,CAAC,cAAc,EAAE,CAAC;4BACrB,IAAI,CAAC,gBAAgB,EAAE,CAAC;gCACpB,GAAG,CAAC,cAAc,EAAE,CAAC;4BACzB,CAAC;wBACL,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACI,aAAa;QAChB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,IAAI,CAAC,mBAAmB,EAAE,MAAM,EAAE,CAAC;YACnC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;YAChC,IAAI,CAAC,qBAAqB,EAAE,MAAM,EAAE,CAAC;YACrC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QACtC,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACI,WAAW;QACd,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YAE3B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;gBACrD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBAClC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;oBACpB,WAAW;oBACX,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;wBACxC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC,IAAI,IAAI,CAAC,mBAAmB,CAAC;oBAC5E,CAAC;yBAAM,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;wBAChD,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC,IAAI,IAAI,CAAC,mBAAmB,CAAC;oBAC5E,CAAC;yBAAM,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;wBAC7C,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC,IAAI,IAAI,CAAC,mBAAmB,CAAC;oBAC5E,CAAC;yBAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;wBAC/C,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC,IAAI,IAAI,CAAC,mBAAmB,CAAC;oBAC5E,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,OAAO;oBACP,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;wBAC1C,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;oBAC5D,CAAC;yBAAM,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;wBAClD,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;oBAC7D,CAAC;yBAAM,CAAC;wBACJ,6HAA6H;wBAC7H,6GAA6G;wBAC7G,mIAAmI;wBACnI,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,uBAAuB,EAAE,CAAC;wBAC/D,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,GAAG,eAAe,CAAC;wBACtE,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC,GAAG,eAAe,CAAC;wBACvE,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;wBAC5C,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;4BACxC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;wBACvE,CAAC;6BAAM,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;4BAChD,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;wBACvE,CAAC;6BAAM,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;4BAC7C,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;wBACvE,CAAC;6BAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;4BAC/C,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;wBACvE,CAAC;wBACD,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;oBAC/B,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED;;;OAGG;IACI,YAAY;QACf,OAAO,+BAA+B,CAAC;IAC3C,CAAC;IAED;;;OAGG;IACI,aAAa;QAChB,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ;AAnNU;IADN,SAAS,EAAE;6DACS;AAMd;IADN,SAAS,EAAE;+DACW;AAMhB;IADN,SAAS,EAAE;+DACW;AAMhB;IADN,SAAS,EAAE;gEACY;AAMjB;IADN,SAAS,EAAE;iEACmB;AAMxB;IADN,SAAS,EAAE;kEACoB;AAOzB;IADN,SAAS,EAAE;0EACqB;AAO1B;IADN,SAAS,EAAE;qEACwB;AAO7B;IADN,SAAS,EAAE;sEACyB;AAkKnC,gBAAiB,CAAC,+BAA+B,CAAC,GAAG,6BAA6B,CAAC","sourcesContent":["import type { Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport type { Observer } from \"../../Misc/observable\";\r\nimport type { Scene } from \"../../scene\";\r\nimport type { GeospatialCamera } from \"../geospatialCamera\";\r\nimport type { ICameraInput } from \"../cameraInputsManager\";\r\nimport { CameraInputTypes } from \"../cameraInputsManager\";\r\nimport type { KeyboardInfo } from \"../../Events/keyboardEvents\";\r\nimport { KeyboardEventTypes } from \"../../Events/keyboardEvents\";\r\nimport { Tools } from \"../../Misc/tools\";\r\nimport type { AbstractEngine } from \"../../Engines/abstractEngine\";\r\n\r\n/**\r\n * Manage the keyboard inputs to control the movement of a geospatial camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class GeospatialCameraKeyboardInput implements ICameraInput<GeospatialCamera> {\r\n /**\r\n * Defines the camera the input is attached to.\r\n */\r\n public camera: GeospatialCamera;\r\n\r\n /**\r\n * Defines the list of key codes associated with the up action (pan up)\r\n */\r\n @serialize()\r\n public keysUp = [38];\r\n\r\n /**\r\n * Defines the list of key codes associated with the down action (pan down)\r\n */\r\n @serialize()\r\n public keysDown = [40];\r\n\r\n /**\r\n * Defines the list of key codes associated with the left action (pan left)\r\n */\r\n @serialize()\r\n public keysLeft = [37];\r\n\r\n /**\r\n * Defines the list of key codes associated with the right action (pan right)\r\n */\r\n @serialize()\r\n public keysRight = [39];\r\n\r\n /**\r\n * Defines the list of key codes associated with zoom in (+ or =)\r\n */\r\n @serialize()\r\n public keysZoomIn = [187, 107]; // 187 = + key, 107 = numpad +\r\n\r\n /**\r\n * Defines the list of key codes associated with zoom out (-)\r\n */\r\n @serialize()\r\n public keysZoomOut = [189, 109]; // 189 = - key, 109 = numpad -\r\n\r\n /**\r\n * Defines the rotation sensitivity of the inputs.\r\n * (How many pixels of pointer input to apply per keypress, before rotation speed factor is applied by movement class)\r\n */\r\n @serialize()\r\n public rotationSensitivity = 1.0;\r\n\r\n /**\r\n * Defines the panning sensitivity of the inputs.\r\n * (How many pixels of pointer input to apply per keypress, before pan speed factor is applied by movement class)\r\n */\r\n @serialize()\r\n public panSensitivity: number = 1.0;\r\n\r\n /**\r\n * Defines the zooming sensitivity of the inputs.\r\n * (How many pixels of pointer input to apply per keypress, before zoom speed factor is applied by movement class)\r\n */\r\n @serialize()\r\n public zoomSensitivity: number = 1.0;\r\n\r\n private _keys = new Array<number>();\r\n private _ctrlPressed: boolean;\r\n private _onCanvasBlurObserver: Nullable<Observer<AbstractEngine>>;\r\n private _onKeyboardObserver: Nullable<Observer<KeyboardInfo>>;\r\n private _engine: AbstractEngine;\r\n private _scene: Scene;\r\n\r\n /**\r\n * Attach the input controls to a specific dom element to get the input from.\r\n * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)\r\n */\r\n public attachControl(noPreventDefault?: boolean): void {\r\n // was there a second variable defined?\r\n noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\r\n\r\n if (this._onCanvasBlurObserver) {\r\n return;\r\n }\r\n\r\n this._scene = this.camera.getScene();\r\n this._engine = this._scene.getEngine();\r\n\r\n this._onCanvasBlurObserver = this._engine.onCanvasBlurObservable.add(() => {\r\n this._keys.length = 0;\r\n });\r\n\r\n this._onKeyboardObserver = this._scene.onKeyboardObservable.add((info) => {\r\n const evt = info.event;\r\n if (!evt.metaKey) {\r\n if (info.type === KeyboardEventTypes.KEYDOWN) {\r\n this._ctrlPressed = evt.ctrlKey;\r\n\r\n if (\r\n this.keysUp.indexOf(evt.keyCode) !== -1 ||\r\n this.keysDown.indexOf(evt.keyCode) !== -1 ||\r\n this.keysLeft.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRight.indexOf(evt.keyCode) !== -1 ||\r\n this.keysZoomIn.indexOf(evt.keyCode) !== -1 ||\r\n this.keysZoomOut.indexOf(evt.keyCode) !== -1\r\n ) {\r\n const index = this._keys.indexOf(evt.keyCode);\r\n\r\n if (index === -1) {\r\n this._keys.push(evt.keyCode);\r\n }\r\n\r\n if (evt.preventDefault) {\r\n if (!noPreventDefault) {\r\n evt.preventDefault();\r\n }\r\n }\r\n }\r\n } else {\r\n if (\r\n this.keysUp.indexOf(evt.keyCode) !== -1 ||\r\n this.keysDown.indexOf(evt.keyCode) !== -1 ||\r\n this.keysLeft.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRight.indexOf(evt.keyCode) !== -1 ||\r\n this.keysZoomIn.indexOf(evt.keyCode) !== -1 ||\r\n this.keysZoomOut.indexOf(evt.keyCode) !== -1\r\n ) {\r\n const index = this._keys.indexOf(evt.keyCode);\r\n\r\n if (index >= 0) {\r\n this._keys.splice(index, 1);\r\n }\r\n\r\n if (evt.preventDefault) {\r\n if (!noPreventDefault) {\r\n evt.preventDefault();\r\n }\r\n }\r\n }\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Detach the current controls from the specified dom element.\r\n */\r\n public detachControl(): void {\r\n if (this._scene) {\r\n this._onKeyboardObserver?.remove();\r\n this._onKeyboardObserver = null;\r\n this._onCanvasBlurObserver?.remove();\r\n this._onCanvasBlurObserver = null;\r\n }\r\n\r\n this._keys.length = 0;\r\n }\r\n\r\n /**\r\n * Update the current camera state depending on the inputs that have been used this frame.\r\n * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.\r\n */\r\n public checkInputs(): void {\r\n if (this._onKeyboardObserver) {\r\n const camera = this.camera;\r\n\r\n for (let index = 0; index < this._keys.length; index++) {\r\n const keyCode = this._keys[index];\r\n if (this._ctrlPressed) {\r\n // Rotation\r\n if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n camera.movement.rotationAccumulatedPixels.y -= this.rotationSensitivity;\r\n } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n camera.movement.rotationAccumulatedPixels.y += this.rotationSensitivity;\r\n } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n camera.movement.rotationAccumulatedPixels.x -= this.rotationSensitivity;\r\n } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n camera.movement.rotationAccumulatedPixels.x += this.rotationSensitivity;\r\n }\r\n } else {\r\n // Zoom\r\n if (this.keysZoomIn.indexOf(keyCode) !== -1) {\r\n camera.movement.handleZoom(this.zoomSensitivity, false);\r\n } else if (this.keysZoomOut.indexOf(keyCode) !== -1) {\r\n camera.movement.handleZoom(-this.zoomSensitivity, false);\r\n } else {\r\n // Call into movement class handleDrag so that behavior matches that of pointer input, simulating drag from center of screen.\r\n // getRenderWidth/Height return render buffer pixels (scaled by hardwareScalingLevel relative to CSS pixels),\r\n // but the picking logic (scene.pick via CreatePickingRayToRef) expects CSS pixels (it divides by hardwareScalingLevel internally).\r\n const hardwareScaling = this._engine.getHardwareScalingLevel();\r\n const centerX = (this._engine.getRenderWidth() / 2) * hardwareScaling;\r\n const centerY = (this._engine.getRenderHeight() / 2) * hardwareScaling;\r\n camera.movement.startDrag(centerX, centerY);\r\n if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n camera.movement.handleDrag(centerX + this.panSensitivity, centerY);\r\n } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n camera.movement.handleDrag(centerX - this.panSensitivity, centerY);\r\n } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n camera.movement.handleDrag(centerX, centerY + this.panSensitivity);\r\n } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n camera.movement.handleDrag(centerX, centerY - this.panSensitivity);\r\n }\r\n camera.movement.stopDrag();\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Gets the class name of the current input.\r\n * @returns the class name\r\n */\r\n public getClassName(): string {\r\n return \"GeospatialCameraKeyboardInput\";\r\n }\r\n\r\n /**\r\n * Get the friendly name associated with the input class.\r\n * @returns the input friendly name\r\n */\r\n public getSimpleName(): string {\r\n return \"keyboard\";\r\n }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"GeospatialCameraKeyboardInput\"] = GeospatialCameraKeyboardInput;\r\n"]}
@@ -162,9 +162,10 @@ export declare class GeospatialCamera extends Camera {
162
162
  * @param center - The center point on the globe
163
163
  * @param useRightHandedSystem - Whether the scene uses a right-handed coordinate system
164
164
  * @param result - The vector to store the result in
165
+ * @param calculateUpVectorFromPoint - Optional function to calculate the up vector from a point, allowing for non-spherical planets. If not supplied, a perfect sphere is assumed and the up vector is just the normalized center point.
165
166
  * @returns The normalized lookAt direction vector (same as result)
166
167
  */
167
- export declare function ComputeLookAtFromYawPitchToRef(yaw: number, pitch: number, center: Vector3, useRightHandedSystem: boolean, result: Vector3): Vector3;
168
+ export declare function ComputeLookAtFromYawPitchToRef(yaw: number, pitch: number, center: Vector3, useRightHandedSystem: boolean, result: Vector3, calculateUpVectorFromPoint?: (point: Vector3, result: Vector3) => Vector3): Vector3;
168
169
  /**
169
170
  * Given a lookAt direction and center, compute the yaw and pitch angles that would produce that lookAt.
170
171
  * This is the inverse of ComputeLookAtFromYawPitchToRef.
@@ -173,6 +174,7 @@ export declare function ComputeLookAtFromYawPitchToRef(yaw: number, pitch: numbe
173
174
  * @param useRightHandedSystem - Whether the scene uses a right-handed coordinate system
174
175
  * @param currentYaw - The current yaw value to use as fallback when pitch is near 0 (looking straight down/up)
175
176
  * @param result - The Vector2 to store the result in (x = yaw, y = pitch)
177
+ * @param calculateUpVectorFromPoint - Optional function to calculate the up vector from a point. If supplied, this function will be used instead of assuming a spherical geocentric normal, allowing support for non-spherical planets or custom up vector logic.
176
178
  * @returns The result Vector2
177
179
  */
178
- export declare function ComputeYawPitchFromLookAtToRef(lookAt: Vector3, center: Vector3, useRightHandedSystem: boolean, currentYaw: number, result: Vector2): Vector2;
180
+ export declare function ComputeYawPitchFromLookAtToRef(lookAt: Vector3, center: Vector3, useRightHandedSystem: boolean, currentYaw: number, result: Vector2, calculateUpVectorFromPoint?: (point: Vector3, result: Vector3) => Vector3): Vector2;
@@ -37,10 +37,10 @@ export class GeospatialCamera extends Camera {
37
37
  this._tempUp = new Vector3();
38
38
  this._wasCenterMovingLastFrame = false;
39
39
  this._limits = new GeospatialLimits(options.planetRadius);
40
- this._resetToDefault(this._limits);
41
40
  this._flyingBehavior = new InterpolatingBehavior();
42
41
  this.addBehavior(this._flyingBehavior);
43
42
  this.movement = new GeospatialCameraMovement(scene, this._limits, this.position, this.center, this._lookAtVector, options.pickPredicate, this._flyingBehavior);
43
+ this._resetToDefault(this._limits);
44
44
  this.inputs = new GeospatialCameraInputsManager(this);
45
45
  this.inputs.addMouse().addMouseWheel().addKeyboard();
46
46
  }
@@ -113,9 +113,9 @@ export class GeospatialCamera extends Camera {
113
113
  // Clamp to limits
114
114
  this._checkLimits();
115
115
  // Refresh local basis at center (treat these as read-only for the whole call)
116
- ComputeLocalBasisToRefs(this._center, this._tempEast, this._tempNorth, this._tempUp, this._scene.useRightHandedSystem);
116
+ ComputeLocalBasisToRefs(this._center, this._tempEast, this._tempNorth, this._tempUp, this._scene.useRightHandedSystem, this.movement.calculateUpVectorFromPoint);
117
117
  // Compute lookAt from yaw/pitch
118
- ComputeLookAtFromYawPitchToRef(this._yaw, this._pitch, this._center, this._scene.useRightHandedSystem, this._lookAtVector);
118
+ ComputeLookAtFromYawPitchToRef(this._yaw, this._pitch, this._center, this._scene.useRightHandedSystem, this._lookAtVector, this.movement.calculateUpVectorFromPoint);
119
119
  // Build an orthonormal up aligned with geocentric Up
120
120
  // When looking straight down (pitch ≈ 0), lookAt is parallel to Up, so use the horizontal direction as the camera's up.
121
121
  const right = TmpVectors.Vector3[10];
@@ -394,7 +394,7 @@ export class GeospatialCamera extends Camera {
394
394
  if (newRadius > Epsilon) {
395
395
  // Compute yaw/pitch that correspond to current lookAt at new center
396
396
  const yawPitch = TmpVectors.Vector2[0];
397
- ComputeYawPitchFromLookAtToRef(this._lookAtVector, newCenter.pickedPoint, this._scene.useRightHandedSystem, this._yaw, yawPitch);
397
+ ComputeYawPitchFromLookAtToRef(this._lookAtVector, newCenter.pickedPoint, this._scene.useRightHandedSystem, this._yaw, yawPitch, this.movement.calculateUpVectorFromPoint);
398
398
  // Call _setOrientation with the computed yaw/pitch and new center
399
399
  this._setOrientation(yawPitch.x, yawPitch.y, newRadius, newCenter.pickedPoint);
400
400
  }
@@ -467,13 +467,14 @@ RegisterClass("BABYLON.GeospatialCamera", GeospatialCamera);
467
467
  * @param center - The center point on the globe
468
468
  * @param useRightHandedSystem - Whether the scene uses a right-handed coordinate system
469
469
  * @param result - The vector to store the result in
470
+ * @param calculateUpVectorFromPoint - Optional function to calculate the up vector from a point, allowing for non-spherical planets. If not supplied, a perfect sphere is assumed and the up vector is just the normalized center point.
470
471
  * @returns The normalized lookAt direction vector (same as result)
471
472
  */
472
- export function ComputeLookAtFromYawPitchToRef(yaw, pitch, center, useRightHandedSystem, result) {
473
+ export function ComputeLookAtFromYawPitchToRef(yaw, pitch, center, useRightHandedSystem, result, calculateUpVectorFromPoint) {
473
474
  const east = TmpVectors.Vector3[0];
474
475
  const north = TmpVectors.Vector3[1];
475
476
  const up = TmpVectors.Vector3[2];
476
- ComputeLocalBasisToRefs(center, east, north, up, useRightHandedSystem);
477
+ ComputeLocalBasisToRefs(center, east, north, up, useRightHandedSystem, calculateUpVectorFromPoint);
477
478
  const sinPitch = Math.sin(pitch);
478
479
  const cosPitch = Math.cos(pitch);
479
480
  // horiz = north * cos(yaw) + east * sin(yaw)
@@ -497,14 +498,15 @@ export function ComputeLookAtFromYawPitchToRef(yaw, pitch, center, useRightHande
497
498
  * @param useRightHandedSystem - Whether the scene uses a right-handed coordinate system
498
499
  * @param currentYaw - The current yaw value to use as fallback when pitch is near 0 (looking straight down/up)
499
500
  * @param result - The Vector2 to store the result in (x = yaw, y = pitch)
501
+ * @param calculateUpVectorFromPoint - Optional function to calculate the up vector from a point. If supplied, this function will be used instead of assuming a spherical geocentric normal, allowing support for non-spherical planets or custom up vector logic.
500
502
  * @returns The result Vector2
501
503
  */
502
- export function ComputeYawPitchFromLookAtToRef(lookAt, center, useRightHandedSystem, currentYaw, result) {
504
+ export function ComputeYawPitchFromLookAtToRef(lookAt, center, useRightHandedSystem, currentYaw, result, calculateUpVectorFromPoint) {
503
505
  // Compute local basis at center
504
506
  const east = TmpVectors.Vector3[6];
505
507
  const north = TmpVectors.Vector3[7];
506
508
  const up = TmpVectors.Vector3[8];
507
- ComputeLocalBasisToRefs(center, east, north, up, useRightHandedSystem);
509
+ ComputeLocalBasisToRefs(center, east, north, up, useRightHandedSystem, calculateUpVectorFromPoint);
508
510
  // lookAt = horiz*sinPitch - up*cosPitch
509
511
  // where horiz = north*cos(yaw) + east*sin(yaw)
510
512
  //
@@ -1 +1 @@
1
- {"version":3,"file":"geospatialCamera.js","sourceRoot":"","sources":["../../../../dev/core/src/Cameras/geospatialCamera.ts"],"names":[],"mappings":"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","sourcesContent":["import { GeospatialCameraInputsManager } from \"./geospatialCameraInputsManager\";\r\nimport { Vector3, Matrix, TmpVectors } from \"../Maths/math.vector\";\r\nimport type { Vector2 } from \"../Maths/math.vector\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\nimport { Camera } from \"./camera\";\r\nimport { serialize, serializeAsVector3 } from \"../Misc/decorators\";\r\nimport type { Scene } from \"../scene\";\r\nimport type { MeshPredicate } from \"../Culling/ray.core\";\r\nimport type { DeepImmutable } from \"../types\";\r\nimport { GeospatialLimits } from \"./Limits/geospatialLimits\";\r\nimport { ClampCenterFromPolesInPlace, ComputeLocalBasisToRefs, GeospatialCameraMovement } from \"./geospatialCameraMovement\";\r\nimport type { IVector3Like } from \"../Maths/math.like\";\r\nimport { Vector3CopyToRef, Vector3Distance, Vector3Dot, Vector3SubtractToRef } from \"../Maths/math.vector.functions\";\r\nimport { Clamp, NormalizeRadians } from \"../Maths/math.scalar.functions\";\r\nimport type { AllowedAnimValue } from \"../Behaviors/Cameras/interpolatingBehavior\";\r\nimport { InterpolatingBehavior } from \"../Behaviors/Cameras/interpolatingBehavior\";\r\nimport type { Collider } from \"../Collisions/collider\";\r\nimport type { EasingFunction } from \"../Animations/easing\";\r\nimport type { Animation } from \"../Animations/animation\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\nexport type GeospatialCameraOptions = {\r\n /**\r\n * Radius of the planet being orbited\r\n */\r\n planetRadius: number;\r\n /**\r\n * If supplied, will be used by the movement class when picking the globe. Can later update camera.movement.pickPredicate directly\r\n */\r\n pickPredicate?: MeshPredicate;\r\n};\r\n\r\n/**\r\n * Camera equipped to orbit a spherical planet centered at world origin\r\n */\r\nexport class GeospatialCamera extends Camera {\r\n override inputs: GeospatialCameraInputsManager;\r\n\r\n /** Movement controller that turns input pixelDeltas into currentFrameDeltas used by camera*/\r\n public readonly movement: GeospatialCameraMovement;\r\n\r\n // Temp vars\r\n private _tempPosition: Vector3 = new Vector3();\r\n private _tempCenter: Vector3 = new Vector3();\r\n\r\n private _viewMatrix = new Matrix();\r\n private _isViewMatrixDirty: boolean;\r\n private _lookAtVector: Vector3 = new Vector3();\r\n\r\n /** Behavior used for smooth flying animations */\r\n private _flyingBehavior: InterpolatingBehavior<GeospatialCamera>;\r\n private _flyToTargets: Map<keyof GeospatialCamera, AllowedAnimValue> = new Map();\r\n\r\n // Collision properties\r\n private _collider?: Collider;\r\n private _collisionVelocity: Vector3 = new Vector3();\r\n /** Public option to customize the collision offset applied each frame - vs the one calculated using internal CollisionCoordinator */\r\n public perFrameCollisionOffset: Vector3 = new Vector3();\r\n /** Enable or disable collision checking for this camera. Default is false. */\r\n @serialize()\r\n public checkCollisions: boolean = false;\r\n\r\n constructor(name: string, scene: Scene, options: GeospatialCameraOptions) {\r\n super(name, new Vector3(), scene);\r\n\r\n this._limits = new GeospatialLimits(options.planetRadius);\r\n this._resetToDefault(this._limits);\r\n\r\n this._flyingBehavior = new InterpolatingBehavior();\r\n this.addBehavior(this._flyingBehavior);\r\n\r\n this.movement = new GeospatialCameraMovement(scene, this._limits, this.position, this.center, this._lookAtVector, options.pickPredicate, this._flyingBehavior);\r\n\r\n this.inputs = new GeospatialCameraInputsManager(this);\r\n this.inputs.addMouse().addMouseWheel().addKeyboard();\r\n }\r\n\r\n @serializeAsVector3()\r\n private _center: Vector3 = new Vector3();\r\n /** The point on the globe that we are anchoring around. If no alternate rotation point is supplied, this will represent the center of screen*/\r\n public get center(): Vector3 {\r\n return this._center;\r\n }\r\n\r\n /**\r\n * Sets the camera position to orbit around a new center point\r\n * @param center The world position (ECEF) to orbit around\r\n */\r\n public set center(center: IVector3Like) {\r\n this._center.copyFromFloats(center.x, center.y, center.z);\r\n this._setOrientation(this._yaw, this._pitch, this._radius, this._center);\r\n }\r\n\r\n @serialize()\r\n private _yaw: number = 0;\r\n /**\r\n * Gets the camera's yaw (rotation around the geocentric normal) in radians\r\n */\r\n public get yaw(): number {\r\n return this._yaw;\r\n }\r\n\r\n /**\r\n * Sets the camera's yaw (rotation around the geocentric normal). Will wrap value to [-π, π)\r\n * @param yaw The desired yaw angle in radians (0 = north, π/2 = east)\r\n */\r\n public set yaw(yaw: number) {\r\n yaw !== this._yaw && this._setOrientation(yaw, this.pitch, this.radius, this.center);\r\n }\r\n\r\n @serialize()\r\n private _pitch: number = 0;\r\n\r\n /**\r\n * Gets the camera's pitch (angle from looking straight at globe)\r\n * Pitch is measured from looking straight down at planet center:\r\n * - zero pitch = looking straight at planet center (down)\r\n * - positive pitch = tilting up away from planet\r\n * - π/2 pitch = looking at horizon (perpendicular to geocentric normal)\r\n */\r\n public get pitch(): number {\r\n return this._pitch;\r\n }\r\n\r\n /**\r\n * Sets the camera's pitch (angle from looking straight at globe). Will wrap value to [-π, π)\r\n * @param pitch The desired pitch angle in radians (0 = looking at planet center, π/2 = looking at horizon)\r\n */\r\n public set pitch(pitch: number) {\r\n pitch !== this._pitch && this._setOrientation(this.yaw, pitch, this.radius, this.center);\r\n }\r\n\r\n @serialize()\r\n private _radius: number = 0;\r\n public get radius(): number {\r\n return this._radius;\r\n }\r\n\r\n /**\r\n * Sets the camera's distance from the current center point\r\n * @param radius The desired radius\r\n */\r\n public set radius(radius: number) {\r\n radius !== this._radius && this._setOrientation(this.yaw, this.pitch, radius, this.center);\r\n }\r\n\r\n protected _checkLimits() {\r\n const limits = this.limits;\r\n this._yaw = Clamp(this._yaw, limits.yawMin, limits.yawMax);\r\n const effectivePitchMax = limits.getEffectivePitchMax(this._radius);\r\n this._pitch = Clamp(this._pitch, limits.pitchMin, effectivePitchMax);\r\n this._radius = Clamp(this._radius, limits.radiusMin, limits.radiusMax);\r\n ClampCenterFromPolesInPlace(this._center);\r\n }\r\n\r\n private _tempVect = new Vector3();\r\n private _tempEast = new Vector3();\r\n private _tempNorth = new Vector3();\r\n private _tempUp = new Vector3();\r\n\r\n private _setOrientation(yaw: number, pitch: number, radius: number, center: DeepImmutable<IVector3Like>): void {\r\n // Wrap yaw and pitch to [-π, π)\r\n this._yaw = NormalizeRadians(yaw);\r\n this._pitch = NormalizeRadians(pitch);\r\n this._radius = radius;\r\n\r\n Vector3CopyToRef(center, this._center);\r\n\r\n // Clamp to limits\r\n this._checkLimits();\r\n\r\n // Refresh local basis at center (treat these as read-only for the whole call)\r\n ComputeLocalBasisToRefs(this._center, this._tempEast, this._tempNorth, this._tempUp, this._scene.useRightHandedSystem);\r\n\r\n // Compute lookAt from yaw/pitch\r\n ComputeLookAtFromYawPitchToRef(this._yaw, this._pitch, this._center, this._scene.useRightHandedSystem, this._lookAtVector);\r\n\r\n // Build an orthonormal up aligned with geocentric Up\r\n // When looking straight down (pitch ≈ 0), lookAt is parallel to Up, so use the horizontal direction as the camera's up.\r\n const right = TmpVectors.Vector3[10];\r\n Vector3.CrossToRef(this._tempUp, this._lookAtVector, right);\r\n if (right.lengthSquared() < Epsilon) {\r\n // horiz = north * cos(yaw) + east * sin(yaw)\r\n // Using tempEast directly ensures handedness is taken into account\r\n const horiz = TmpVectors.Vector3[11];\r\n const t1 = TmpVectors.Vector3[12];\r\n horiz\r\n .copyFrom(this._tempNorth)\r\n .scaleInPlace(Math.cos(this._yaw))\r\n .addInPlace(t1.copyFrom(this._tempEast).scaleInPlace(Math.sin(this._yaw)));\r\n // right = cross(horiz, lookAt)\r\n Vector3.CrossToRef(horiz, this._lookAtVector, right);\r\n }\r\n right.normalize();\r\n\r\n // up = normalize(cross(look, right))\r\n Vector3.CrossToRef(this._lookAtVector, right, this.upVector);\r\n this.upVector.normalize();\r\n\r\n // Position = center - look * radius (preserve unit look)\r\n this._tempVect.copyFrom(this._lookAtVector).scaleInPlace(-this._radius);\r\n this._tempPosition.copyFrom(this._center).addInPlace(this._tempVect);\r\n\r\n // Recalculate collisionOffset to be applied later when viewMatrix is calculated (allowing camera users to modify the value in afterCheckInputsObservable)\r\n if (this.checkCollisions) {\r\n this.perFrameCollisionOffset = this._getCollisionOffset(this._tempPosition);\r\n }\r\n\r\n this._position.copyFrom(this._tempPosition);\r\n\r\n this._isViewMatrixDirty = true;\r\n }\r\n\r\n /**\r\n * If camera is actively in flight, will update the target properties and use up the remaining duration from original flyTo call\r\n *\r\n * To start a new flyTo curve entirely, call into flyToAsync again (it will stop the inflight animation)\r\n * @param targetYaw\r\n * @param targetPitch\r\n * @param targetRadius\r\n * @param targetCenter\r\n */\r\n public updateFlyToDestination(targetYaw?: number, targetPitch?: number, targetRadius?: number, targetCenter?: Vector3): void {\r\n this._flyToTargets.clear();\r\n\r\n // For yaw, use shortest path to target.\r\n const deltaYaw = targetYaw !== undefined ? NormalizeRadians(NormalizeRadians(targetYaw) - this._yaw) : 0;\r\n this._flyToTargets.set(\"yaw\", deltaYaw === 0 ? undefined : this._yaw + deltaYaw);\r\n this._flyToTargets.set(\"pitch\", targetPitch != undefined ? NormalizeRadians(targetPitch) : undefined);\r\n this._flyToTargets.set(\"radius\", targetRadius);\r\n this._flyToTargets.set(\"center\", targetCenter?.clone());\r\n\r\n this._flyingBehavior.updateProperties(this._flyToTargets);\r\n }\r\n\r\n /**\r\n * Animate camera towards passed in property values. If undefined, will use current value\r\n * @param targetYaw\r\n * @param targetPitch\r\n * @param targetRadius\r\n * @param targetCenter\r\n * @param flightDurationMs\r\n * @param easingFunction\r\n * @param centerHopScale If supplied, will define the parabolic hop height scale for center animation to create a \"bounce\" effect\r\n * @returns Promise that will return when the animation is complete (or interuppted by pointer input)\r\n */\r\n public async flyToAsync(\r\n targetYaw?: number,\r\n targetPitch?: number,\r\n targetRadius?: number,\r\n targetCenter?: Vector3,\r\n flightDurationMs: number = 1000,\r\n easingFunction?: EasingFunction,\r\n centerHopScale?: number\r\n ): Promise<void> {\r\n this._flyToTargets.clear();\r\n\r\n // For yaw, use shortest path to target.\r\n const deltaYaw = targetYaw !== undefined ? NormalizeRadians(NormalizeRadians(targetYaw) - this._yaw) : 0;\r\n this._flyToTargets.set(\"yaw\", deltaYaw === 0 ? undefined : this._yaw + deltaYaw);\r\n this._flyToTargets.set(\"pitch\", targetPitch !== undefined ? NormalizeRadians(targetPitch) : undefined);\r\n this._flyToTargets.set(\"radius\", targetRadius);\r\n this._flyToTargets.set(\"center\", targetCenter?.clone());\r\n\r\n let overrideAnimationFunction;\r\n if (targetCenter !== undefined && !targetCenter.equals(this.center)) {\r\n // Animate center directly with custom interpolation\r\n overrideAnimationFunction = (key: string, animation: Animation): void => {\r\n if (key === \"center\") {\r\n // Override the Vector3 interpolation to use SLERP + hop\r\n animation.vector3InterpolateFunction = (startValue, endValue, gradient) => {\r\n // gradient is the eased value (0 to 1) after easing function is applied\r\n\r\n // Slerp between start and end\r\n const newCenter = Vector3.SlerpToRef(startValue, endValue, gradient, this._tempCenter);\r\n\r\n // Apply parabolic hop if requested\r\n if (centerHopScale && centerHopScale > 0) {\r\n // Parabolic formula: peaks at t=0.5, returns to 0 at gradient=0 and gradient=1\r\n // if hopPeakT = .5 the denominator would be hopPeakT * hopPeakT - hopPeakT, which = -.25\r\n const hopPeakOffset = centerHopScale * Vector3Distance(startValue, endValue);\r\n const hopOffset = hopPeakOffset * Clamp((gradient * gradient - gradient) / -0.25);\r\n // Scale the center outward (away from origin)\r\n newCenter.scaleInPlace(1 + hopOffset / newCenter.length());\r\n }\r\n\r\n return newCenter;\r\n };\r\n }\r\n };\r\n }\r\n\r\n return await this._flyingBehavior.animatePropertiesAsync(this._flyToTargets, flightDurationMs, easingFunction, overrideAnimationFunction);\r\n }\r\n\r\n /**\r\n * Helper function to move camera towards a given point by `distanceScale` of the current camera-to-destination distance (by default 50%).\r\n * @param destination point to move towards\r\n * @param distanceScale value between 0 and 1, % of distance to move\r\n * @param durationMs duration of flight, default 1s\r\n * @param easingFn optional easing function for flight interpolation of properties\r\n * @param centerHopScale If supplied, will define the parabolic hop height scale for center animation to create a \"bounce\" effect\r\n */\r\n public async flyToPointAsync(destination: Vector3, distanceScale: number = 0.5, durationMs: number = 1000, easingFn?: EasingFunction, centerHopScale?: number) {\r\n // Move by a fraction of the camera-to-destination distance\r\n const zoomDistance = Vector3Distance(this.position, destination) * distanceScale;\r\n const newRadius = this._getCenterAndRadiusFromZoomToPoint(destination, zoomDistance, this._tempCenter);\r\n await this.flyToAsync(undefined, undefined, newRadius, this._tempCenter, durationMs, easingFn, centerHopScale);\r\n !this.isDisposed() && this._recalculateCenter(false, true /** force */);\r\n }\r\n\r\n private _limits: GeospatialLimits;\r\n public get limits(): GeospatialLimits {\r\n return this._limits;\r\n }\r\n\r\n private _resetToDefault(limits: GeospatialLimits): void {\r\n // Camera configuration vars\r\n const restingAltitude = limits.radiusMax !== Infinity ? limits.radiusMax : limits.planetRadius * 4;\r\n this.position.copyFromFloats(restingAltitude, 0, 0);\r\n this._center.copyFromFloats(limits.planetRadius, 0, 0);\r\n this._radius = Vector3.Distance(this.position, this.center);\r\n\r\n // Temp vars\r\n this._tempPosition = new Vector3();\r\n\r\n // View matrix calculation vars\r\n this._viewMatrix = Matrix.Identity();\r\n this._center.subtractToRef(this._position, this._lookAtVector).normalize(); // Lookat vector of the camera\r\n this.upVector = Vector3.Up(); // Up vector of the camera (does work for -X look at)\r\n this._isViewMatrixDirty = true;\r\n\r\n this._setOrientation(this._yaw, this._pitch, this._radius, this._center);\r\n }\r\n\r\n /** @internal */\r\n override _getViewMatrix() {\r\n if (!this._isViewMatrixDirty) {\r\n return this._viewMatrix;\r\n }\r\n this._isViewMatrixDirty = false;\r\n\r\n // Ensure vectors are normalized\r\n this.upVector.normalize();\r\n this._lookAtVector.normalize();\r\n\r\n // Apply the same offset to both position and center to preserve orbital relationship\r\n // This keeps yaw/pitch/radius intact - just lifts the whole \"rig\"\r\n this._position.addInPlace(this.perFrameCollisionOffset);\r\n this._center.addInPlace(this.perFrameCollisionOffset);\r\n\r\n // Calculate view matrix with camera position and center\r\n if (this.getScene().useRightHandedSystem) {\r\n Matrix.LookAtRHToRef(this.position, this._center, this.upVector, this._viewMatrix);\r\n } else {\r\n Matrix.LookAtLHToRef(this.position, this._center, this.upVector, this._viewMatrix);\r\n }\r\n\r\n return this._viewMatrix;\r\n }\r\n\r\n /** @internal */\r\n override _isSynchronizedViewMatrix(): boolean {\r\n if (!super._isSynchronizedViewMatrix() || this._isViewMatrixDirty) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n private _applyGeocentricTranslation() {\r\n // Store pending position (without any corrections applied)\r\n this.center.addToRef(this.movement.panDeltaCurrentFrame, this._tempPosition);\r\n\r\n if (!this.movement.isInterpolating) {\r\n // Calculate the position correction to keep camera at the same radius when applying translation\r\n this._tempPosition.normalize().scaleInPlace(this.center.length());\r\n }\r\n // Set center which will call _setOrientation\r\n this.center = this._tempPosition;\r\n }\r\n\r\n /**\r\n * This rotation keeps the camera oriented towards the globe as it orbits around it. This is different from cameraCentricRotation which is when the camera rotates around its own axis\r\n */\r\n private _applyGeocentricRotation(): void {\r\n const rotationDeltaCurrentFrame = this.movement.rotationDeltaCurrentFrame;\r\n if (rotationDeltaCurrentFrame.x !== 0 || rotationDeltaCurrentFrame.y !== 0) {\r\n const pitch = rotationDeltaCurrentFrame.x !== 0 ? Clamp(this._pitch + rotationDeltaCurrentFrame.x, 0, 0.5 * Math.PI - Epsilon) : this._pitch;\r\n const yaw = rotationDeltaCurrentFrame.y !== 0 ? this._yaw + rotationDeltaCurrentFrame.y : this._yaw;\r\n\r\n this._setOrientation(yaw, pitch, this._radius, this._center);\r\n }\r\n }\r\n\r\n private _getCenterAndRadiusFromZoomToPoint(targetPoint: DeepImmutable<IVector3Like>, distance: number, newCenterResult: Vector3): number {\r\n const directionToTarget = Vector3SubtractToRef(targetPoint, this._position, TmpVectors.Vector3[0]);\r\n const distanceToTarget = directionToTarget.length();\r\n\r\n // Don't zoom past the min radius limit.\r\n if (distanceToTarget < this.limits.radiusMin) {\r\n newCenterResult.copyFrom(this._center);\r\n const requestedRadius = this._radius - distance;\r\n const newRadius = Clamp(requestedRadius, this.limits.radiusMin, this.limits.radiusMax);\r\n return newRadius;\r\n }\r\n\r\n // Move the camera position towards targetPoint by distanceToTarget\r\n directionToTarget.scaleInPlace(distance / distanceToTarget);\r\n const newPosition = this._position.addToRef(directionToTarget, TmpVectors.Vector3[1]);\r\n\r\n // Project the movement onto the look vector to derive the new center/radius.\r\n const projectedDistance = Vector3Dot(directionToTarget, this._lookAtVector);\r\n const newRadius = this._radius - projectedDistance;\r\n const newRadiusClamped = Clamp(newRadius, this.limits.radiusMin, this.limits.radiusMax);\r\n newCenterResult.copyFrom(newPosition).addInPlace(this._lookAtVector.scale(newRadiusClamped));\r\n\r\n return newRadiusClamped;\r\n }\r\n\r\n /**\r\n * Apply zoom by moving the camera toward/away from a target point.\r\n */\r\n private _applyZoom() {\r\n let zoomDelta = this.movement.zoomDeltaCurrentFrame;\r\n const pickedPoint = this.movement.computedPerFrameZoomPickPoint;\r\n\r\n // Clamp zoom delta to limits before applying\r\n zoomDelta = this._clampZoomDelta(zoomDelta, pickedPoint);\r\n\r\n if (Math.abs(zoomDelta) < Epsilon) {\r\n return;\r\n }\r\n if (pickedPoint) {\r\n // Zoom toward the picked point under cursor\r\n this.zoomToPoint(pickedPoint, zoomDelta);\r\n } else {\r\n // Zoom along lookAt vector (fallback when no surface under cursor)\r\n this.zoomAlongLookAt(zoomDelta);\r\n }\r\n }\r\n\r\n private _clampZoomDelta(zoomDelta: number, pickedPoint?: Vector3): number {\r\n if (Math.abs(zoomDelta) < Epsilon) {\r\n return 0;\r\n }\r\n\r\n const distanceToTarget = pickedPoint ? Vector3Distance(this._position, pickedPoint) : undefined;\r\n return this.limits.clampZoomDistance(zoomDelta, this._radius, distanceToTarget);\r\n }\r\n\r\n public zoomToPoint(targetPoint: DeepImmutable<IVector3Like>, distance: number) {\r\n const newRadius = this._getCenterAndRadiusFromZoomToPoint(targetPoint, distance, this._tempCenter);\r\n // Apply the new orientation\r\n this._setOrientation(this._yaw, this._pitch, newRadius, this._tempCenter);\r\n }\r\n\r\n public zoomAlongLookAt(distance: number) {\r\n // Clamp radius to limits\r\n const requestedRadius = this._radius - distance;\r\n const newRadius = Clamp(requestedRadius, this.limits.radiusMin, this.limits.radiusMax);\r\n\r\n // Simply change radius without moving center\r\n this._setOrientation(this._yaw, this._pitch, newRadius, this._center);\r\n }\r\n\r\n override _checkInputs(): void {\r\n this.inputs.checkInputs();\r\n this.perFrameCollisionOffset.setAll(0);\r\n\r\n // Let movement class handle all per-frame logic\r\n this.movement.computeCurrentFrameDeltas();\r\n\r\n let isCenterMoving = false;\r\n if (this.movement.panDeltaCurrentFrame.lengthSquared() > 0) {\r\n this._applyGeocentricTranslation();\r\n // After a drag, recalculate the center point to ensure it's still on the surface.\r\n isCenterMoving = true;\r\n }\r\n if (this.movement.rotationDeltaCurrentFrame.lengthSquared() > 0) {\r\n this._applyGeocentricRotation();\r\n }\r\n\r\n if (Math.abs(this.movement.zoomDeltaCurrentFrame) > Epsilon) {\r\n this._applyZoom();\r\n isCenterMoving = true;\r\n }\r\n\r\n // After a movement impacting center or radius, recalculate the center point to ensure it's still on the surface.\r\n this._recalculateCenter(isCenterMoving);\r\n\r\n super._checkInputs();\r\n }\r\n\r\n private _wasCenterMovingLastFrame = false;\r\n\r\n private _recalculateCenter(isCenterMoving: boolean, forceRecalculate: boolean = false): void {\r\n const shouldRecalculateCenterAfterMove = this._wasCenterMovingLastFrame && !isCenterMoving;\r\n this._wasCenterMovingLastFrame = isCenterMoving;\r\n\r\n // Wait until movement impacting center is complete to avoid wasted raycasting\r\n if (shouldRecalculateCenterAfterMove || forceRecalculate) {\r\n const newCenter = this.movement.pickAlongVector(this._lookAtVector);\r\n if (newCenter?.pickedPoint) {\r\n // Direction from new center to origin\r\n const centerToOrigin = TmpVectors.Vector3[4];\r\n centerToOrigin.copyFrom(newCenter.pickedPoint).negateInPlace().normalize();\r\n\r\n // Check if this direction aligns with camera's lookAt vector\r\n const dotProduct = Vector3Dot(this._lookAtVector, centerToOrigin);\r\n\r\n // Only update if the center is looking toward the origin (dot product > 0) to avoid a center on the opposite side of globe\r\n if (dotProduct > 0) {\r\n // Compute the new radius as distance from camera position to new center\r\n const newRadius = Vector3Distance(this._position, newCenter.pickedPoint);\r\n\r\n // Only update if the new center is in front of the camera\r\n if (newRadius > Epsilon) {\r\n // Compute yaw/pitch that correspond to current lookAt at new center\r\n const yawPitch = TmpVectors.Vector2[0];\r\n ComputeYawPitchFromLookAtToRef(this._lookAtVector, newCenter.pickedPoint, this._scene.useRightHandedSystem, this._yaw, yawPitch);\r\n\r\n // Call _setOrientation with the computed yaw/pitch and new center\r\n this._setOrientation(yawPitch.x, yawPitch.y, newRadius, newCenter.pickedPoint);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Allows extended classes to override how collision offset is calculated\r\n * @param newPosition\r\n * @returns\r\n */\r\n protected _getCollisionOffset(newPosition: Vector3): Vector3 {\r\n const collisionOffset = TmpVectors.Vector3[6].setAll(0);\r\n if (!this.checkCollisions || !this._scene.collisionsEnabled) {\r\n return collisionOffset;\r\n }\r\n\r\n const coordinator = this.getScene().collisionCoordinator;\r\n if (!coordinator) {\r\n return collisionOffset;\r\n }\r\n\r\n if (!this._collider) {\r\n this._collider = coordinator.createCollider();\r\n }\r\n this._collider._radius.setAll(this.limits.radiusMin);\r\n\r\n // Calculate velocity from old position to new position\r\n newPosition.subtractToRef(this._position, this._collisionVelocity);\r\n\r\n // Get the collision-adjusted position\r\n const adjustedPosition = coordinator.getNewPosition(this._position, this._collisionVelocity, this._collider, 3, null, () => {}, this.uniqueId);\r\n\r\n // Calculate the collision offset (how much the position was pushed)\r\n adjustedPosition.subtractToRef(newPosition, collisionOffset);\r\n\r\n return collisionOffset;\r\n }\r\n\r\n override attachControl(noPreventDefault?: boolean): void {\r\n this.inputs.attachElement(noPreventDefault);\r\n }\r\n\r\n override detachControl(): void {\r\n this.inputs.detachElement();\r\n }\r\n\r\n /**\r\n * Gets the class name of the camera.\r\n * @returns the class name\r\n */\r\n public override getClassName(): string {\r\n return \"GeospatialCamera\";\r\n }\r\n}\r\n\r\n// Register Class Name\r\nRegisterClass(\"BABYLON.GeospatialCamera\", GeospatialCamera);\r\n\r\n/**\r\n * Compute the lookAt direction vector from yaw and pitch angles at a given center point.\r\n * This is the forward formula used by GeospatialCamera._setOrientation.\r\n * @param yaw - The yaw angle in radians (0 = north, π/2 = east)\r\n * @param pitch - The pitch angle in radians (0 = looking at planet center, π/2 = looking at horizon)\r\n * @param center - The center point on the globe\r\n * @param useRightHandedSystem - Whether the scene uses a right-handed coordinate system\r\n * @param result - The vector to store the result in\r\n * @returns The normalized lookAt direction vector (same as result)\r\n */\r\nexport function ComputeLookAtFromYawPitchToRef(yaw: number, pitch: number, center: Vector3, useRightHandedSystem: boolean, result: Vector3): Vector3 {\r\n const east = TmpVectors.Vector3[0];\r\n const north = TmpVectors.Vector3[1];\r\n const up = TmpVectors.Vector3[2];\r\n ComputeLocalBasisToRefs(center, east, north, up, useRightHandedSystem);\r\n\r\n const sinPitch = Math.sin(pitch);\r\n const cosPitch = Math.cos(pitch);\r\n\r\n // horiz = north * cos(yaw) + east * sin(yaw)\r\n // Handedness is taken into account when defining east vector via ComputeLocalBasisToRefs.\r\n const horiz = TmpVectors.Vector3[3];\r\n const t1 = TmpVectors.Vector3[4];\r\n horiz\r\n .copyFrom(north)\r\n .scaleInPlace(Math.cos(yaw))\r\n .addInPlace(t1.copyFrom(east).scaleInPlace(Math.sin(yaw)));\r\n\r\n // lookAt = horiz * sinPitch - up * cosPitch\r\n const t2 = TmpVectors.Vector3[5];\r\n result.copyFrom(horiz).scaleInPlace(sinPitch).addInPlace(t2.copyFrom(up).scaleInPlace(-cosPitch));\r\n return result.normalize();\r\n}\r\n\r\n/**\r\n * Given a lookAt direction and center, compute the yaw and pitch angles that would produce that lookAt.\r\n * This is the inverse of ComputeLookAtFromYawPitchToRef.\r\n * @param lookAt - The normalized lookAt direction vector\r\n * @param center - The center point on the globe\r\n * @param useRightHandedSystem - Whether the scene uses a right-handed coordinate system\r\n * @param currentYaw - The current yaw value to use as fallback when pitch is near 0 (looking straight down/up)\r\n * @param result - The Vector2 to store the result in (x = yaw, y = pitch)\r\n * @returns The result Vector2\r\n */\r\nexport function ComputeYawPitchFromLookAtToRef(lookAt: Vector3, center: Vector3, useRightHandedSystem: boolean, currentYaw: number, result: Vector2): Vector2 {\r\n // Compute local basis at center\r\n const east = TmpVectors.Vector3[6];\r\n const north = TmpVectors.Vector3[7];\r\n const up = TmpVectors.Vector3[8];\r\n ComputeLocalBasisToRefs(center, east, north, up, useRightHandedSystem);\r\n\r\n // lookAt = horiz*sinPitch - up*cosPitch\r\n // where horiz = north*cos(yaw) + east*sin(yaw)\r\n //\r\n // The vertical component of lookAt (along up) gives us cosPitch:\r\n // lookAt · up = -cosPitch\r\n const lookDotUp = Vector3Dot(lookAt, up);\r\n const cosPitch = -lookDotUp;\r\n\r\n // Clamp cosPitch to valid range to avoid NaN from acos\r\n const clampedCosPitch = Clamp(cosPitch, -1, 1);\r\n const pitch = Math.acos(clampedCosPitch);\r\n\r\n // The horizontal component gives us yaw\r\n // lookHorizontal = lookAt + up*cosPitch = horiz*sinPitch\r\n const lookHorizontal = TmpVectors.Vector3[9];\r\n const scaledUp = TmpVectors.Vector3[10];\r\n scaledUp.copyFrom(up).scaleInPlace(cosPitch);\r\n lookHorizontal.copyFrom(lookAt).addInPlace(scaledUp);\r\n\r\n const sinPitch = Math.sin(pitch);\r\n if (Math.abs(sinPitch) < Epsilon) {\r\n // Looking straight down or up, yaw is undefined - keep current\r\n result.x = currentYaw;\r\n result.y = pitch;\r\n return result;\r\n }\r\n\r\n // horiz = lookHorizontal / sinPitch\r\n const horiz = lookHorizontal.scaleInPlace(1 / sinPitch);\r\n\r\n // From the forward formula: horiz = North*cos(yaw) + East*sin(yaw)\r\n // So: cosYaw = horiz · north, sinYaw = horiz · east\r\n const cosYaw = Vector3Dot(horiz, north);\r\n const sinYaw = Vector3Dot(horiz, east);\r\n\r\n result.x = Math.atan2(sinYaw, cosYaw);\r\n result.y = pitch;\r\n return result;\r\n}\r\n"]}
1
+ {"version":3,"file":"geospatialCamera.js","sourceRoot":"","sources":["../../../../dev/core/src/Cameras/geospatialCamera.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEnE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAInE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAE5H,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACrH,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AAInF,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAalD;;GAEG;AACH,MAAM,OAAO,gBAAiB,SAAQ,MAAM;IA2BxC,YAAY,IAAY,EAAE,KAAY,EAAE,OAAgC;QACpE,KAAK,CAAC,IAAI,EAAE,IAAI,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;QAtBtC,YAAY;QACJ,kBAAa,GAAY,IAAI,OAAO,EAAE,CAAC;QACvC,gBAAW,GAAY,IAAI,OAAO,EAAE,CAAC;QAErC,gBAAW,GAAG,IAAI,MAAM,EAAE,CAAC;QAE3B,kBAAa,GAAY,IAAI,OAAO,EAAE,CAAC;QAIvC,kBAAa,GAAkD,IAAI,GAAG,EAAE,CAAC;QAIzE,uBAAkB,GAAY,IAAI,OAAO,EAAE,CAAC;QACpD,qIAAqI;QAC9H,4BAAuB,GAAY,IAAI,OAAO,EAAE,CAAC;QACxD,8EAA8E;QAEvE,oBAAe,GAAY,KAAK,CAAC;QAkBhC,YAAO,GAAY,IAAI,OAAO,EAAE,CAAC;QAgBjC,SAAI,GAAW,CAAC,CAAC;QAiBjB,WAAM,GAAW,CAAC,CAAC;QAsBnB,YAAO,GAAW,CAAC,CAAC;QAsBpB,cAAS,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,cAAS,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,eAAU,GAAG,IAAI,OAAO,EAAE,CAAC;QAC3B,YAAO,GAAG,IAAI,OAAO,EAAE,CAAC;QA+UxB,8BAAyB,GAAG,KAAK,CAAC;QA5atC,IAAI,CAAC,OAAO,GAAG,IAAI,gBAAgB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAE1D,IAAI,CAAC,eAAe,GAAG,IAAI,qBAAqB,EAAE,CAAC;QACnD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAEvC,IAAI,CAAC,QAAQ,GAAG,IAAI,wBAAwB,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAC/J,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEnC,IAAI,CAAC,MAAM,GAAG,IAAI,6BAA6B,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,aAAa,EAAE,CAAC,WAAW,EAAE,CAAC;IACzD,CAAC;IAID,+IAA+I;IAC/I,IAAW,MAAM;QACb,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAED;;;OAGG;IACH,IAAW,MAAM,CAAC,MAAoB;QAClC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7E,CAAC;IAID;;OAEG;IACH,IAAW,GAAG;QACV,OAAO,IAAI,CAAC,IAAI,CAAC;IACrB,CAAC;IAED;;;OAGG;IACH,IAAW,GAAG,CAAC,GAAW;QACtB,GAAG,KAAK,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACzF,CAAC;IAKD;;;;;;OAMG;IACH,IAAW,KAAK;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED;;;OAGG;IACH,IAAW,KAAK,CAAC,KAAa;QAC1B,KAAK,KAAK,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7F,CAAC;IAID,IAAW,MAAM;QACb,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAED;;;OAGG;IACH,IAAW,MAAM,CAAC,MAAc;QAC5B,MAAM,KAAK,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/F,CAAC;IAES,YAAY;QAClB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3D,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;QACrE,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QACvE,2BAA2B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAOO,eAAe,CAAC,GAAW,EAAE,KAAa,EAAE,MAAc,EAAE,MAAmC;QACnG,gCAAgC;QAChC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QAEtB,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAEvC,kBAAkB;QAClB,IAAI,CAAC,YAAY,EAAE,CAAC;QAEpB,8EAA8E;QAC9E,uBAAuB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC;QAEjK,gCAAgC;QAChC,8BAA8B,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC;QAErK,qDAAqD;QACrD,wHAAwH;QACxH,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACrC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;QAC5D,IAAI,KAAK,CAAC,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;YAClC,6CAA6C;YAC7C,mEAAmE;YACnE,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACrC,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAClC,KAAK;iBACA,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC;iBACzB,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;iBACjC,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC/E,+BAA+B;YAC/B,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;QACzD,CAAC;QACD,KAAK,CAAC,SAAS,EAAE,CAAC;QAElB,qCAAqC;QACrC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7D,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QAE1B,0DAA0D;QAC1D,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAErE,0JAA0J;QAC1J,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAChF,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE5C,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;IACnC,CAAC;IAED;;;;;;;;OAQG;IACI,sBAAsB,CAAC,SAAkB,EAAE,WAAoB,EAAE,YAAqB,EAAE,YAAsB;QACjH,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAE3B,wCAAwC;QACxC,MAAM,QAAQ,GAAG,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAC;QACjF,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,IAAI,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACtG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC/C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;QAExD,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC9D,CAAC;IAED;;;;;;;;;;OAUG;IACI,KAAK,CAAC,UAAU,CACnB,SAAkB,EAClB,WAAoB,EACpB,YAAqB,EACrB,YAAsB,EACtB,mBAA2B,IAAI,EAC/B,cAA+B,EAC/B,cAAuB;QAEvB,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAE3B,wCAAwC;QACxC,MAAM,QAAQ,GAAG,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAC;QACjF,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACvG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC/C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;QAExD,IAAI,yBAAyB,CAAC;QAC9B,IAAI,YAAY,KAAK,SAAS,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAClE,oDAAoD;YACpD,yBAAyB,GAAG,CAAC,GAAW,EAAE,SAAoB,EAAQ,EAAE;gBACpE,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;oBACnB,wDAAwD;oBACxD,SAAS,CAAC,0BAA0B,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;wBACtE,wEAAwE;wBAExE,8BAA8B;wBAC9B,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;wBAEvF,mCAAmC;wBACnC,IAAI,cAAc,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;4BACvC,+EAA+E;4BAC/E,yFAAyF;4BACzF,MAAM,aAAa,GAAG,cAAc,GAAG,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;4BAC7E,MAAM,SAAS,GAAG,aAAa,GAAG,KAAK,CAAC,CAAC,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;4BAClF,8CAA8C;4BAC9C,SAAS,CAAC,YAAY,CAAC,CAAC,GAAG,SAAS,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;wBAC/D,CAAC;wBAED,OAAO,SAAS,CAAC;oBACrB,CAAC,CAAC;gBACN,CAAC;YACL,CAAC,CAAC;QACN,CAAC;QAED,OAAO,MAAM,IAAI,CAAC,eAAe,CAAC,sBAAsB,CAAC,IAAI,CAAC,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,yBAAyB,CAAC,CAAC;IAC9I,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,eAAe,CAAC,WAAoB,EAAE,gBAAwB,GAAG,EAAE,aAAqB,IAAI,EAAE,QAAyB,EAAE,cAAuB;QACzJ,2DAA2D;QAC3D,MAAM,YAAY,GAAG,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,aAAa,CAAC;QACjF,MAAM,SAAS,GAAG,IAAI,CAAC,kCAAkC,CAAC,WAAW,EAAE,YAAY,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACvG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;QAC/G,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5E,CAAC;IAGD,IAAW,MAAM;QACb,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAEO,eAAe,CAAC,MAAwB;QAC5C,4BAA4B;QAC5B,MAAM,eAAe,GAAG,MAAM,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC;QACnG,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAE5D,YAAY;QACZ,IAAI,CAAC,aAAa,GAAG,IAAI,OAAO,EAAE,CAAC;QAEnC,+BAA+B;QAC/B,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,8BAA8B;QAC1G,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,qDAAqD;QACnF,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAE/B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7E,CAAC;IAED,gBAAgB;IACP,cAAc;QACnB,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC,WAAW,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;QAEhC,gCAAgC;QAChC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC;QAE/B,qFAAqF;QACrF,kEAAkE;QAClE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACxD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAEtD,wDAAwD;QACxD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,oBAAoB,EAAE,CAAC;YACvC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACvF,CAAC;aAAM,CAAC;YACJ,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACvF,CAAC;QAED,OAAO,IAAI,CAAC,WAAW,CAAC;IAC5B,CAAC;IAED,gBAAgB;IACP,yBAAyB;QAC9B,IAAI,CAAC,KAAK,CAAC,yBAAyB,EAAE,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAChE,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAEO,2BAA2B;QAC/B,2DAA2D;QAC3D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAE7E,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;YACjC,gGAAgG;YAChG,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,6CAA6C;QAC7C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC;IACrC,CAAC;IAED;;OAEG;IACK,wBAAwB;QAC5B,MAAM,yBAAyB,GAAG,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC;QAC1E,IAAI,yBAAyB,CAAC,CAAC,KAAK,CAAC,IAAI,yBAAyB,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YACzE,MAAM,KAAK,GAAG,yBAAyB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,yBAAyB,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;YAC7I,MAAM,GAAG,GAAG,yBAAyB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAEpG,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACjE,CAAC;IACL,CAAC;IAEO,kCAAkC,CAAC,WAAwC,EAAE,QAAgB,EAAE,eAAwB;QAC3H,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QACnG,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,MAAM,EAAE,CAAC;QAEpD,wCAAwC;QACxC,IAAI,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YAC3C,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvC,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC;YAChD,MAAM,SAAS,GAAG,KAAK,CAAC,eAAe,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACvF,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,mEAAmE;QACnE,iBAAiB,CAAC,YAAY,CAAC,QAAQ,GAAG,gBAAgB,CAAC,CAAC;QAC5D,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAEtF,6EAA6E;QAC7E,MAAM,iBAAiB,GAAG,UAAU,CAAC,iBAAiB,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5E,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,GAAG,iBAAiB,CAAC;QACnD,MAAM,gBAAgB,GAAG,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACxF,eAAe,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAE7F,OAAO,gBAAgB,CAAC;IAC5B,CAAC;IAED;;OAEG;IACK,UAAU;QACd,IAAI,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC;QACpD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,6BAA6B,CAAC;QAEhE,6CAA6C;QAC7C,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAEzD,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,OAAO,EAAE,CAAC;YAChC,OAAO;QACX,CAAC;QACD,IAAI,WAAW,EAAE,CAAC;YACd,4CAA4C;YAC5C,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QAC7C,CAAC;aAAM,CAAC;YACJ,mEAAmE;YACnE,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;IACL,CAAC;IAEO,eAAe,CAAC,SAAiB,EAAE,WAAqB;QAC5D,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,OAAO,EAAE,CAAC;YAChC,OAAO,CAAC,CAAC;QACb,CAAC;QAED,MAAM,gBAAgB,GAAG,WAAW,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAChG,OAAO,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACpF,CAAC;IAEM,WAAW,CAAC,WAAwC,EAAE,QAAgB;QACzE,MAAM,SAAS,GAAG,IAAI,CAAC,kCAAkC,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACnG,4BAA4B;QAC5B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAC9E,CAAC;IAEM,eAAe,CAAC,QAAgB;QACnC,yBAAyB;QACzB,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC;QAChD,MAAM,SAAS,GAAG,KAAK,CAAC,eAAe,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAEvF,6CAA6C;QAC7C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1E,CAAC;IAEQ,YAAY;QACjB,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAC1B,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAEvC,gDAAgD;QAChD,IAAI,CAAC,QAAQ,CAAC,yBAAyB,EAAE,CAAC;QAE1C,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,IAAI,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,aAAa,EAAE,GAAG,CAAC,EAAE,CAAC;YACzD,IAAI,CAAC,2BAA2B,EAAE,CAAC;YACnC,kFAAkF;YAClF,cAAc,GAAG,IAAI,CAAC;QAC1B,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC,aAAa,EAAE,GAAG,CAAC,EAAE,CAAC;YAC9D,IAAI,CAAC,wBAAwB,EAAE,CAAC;QACpC,CAAC;QAED,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,GAAG,OAAO,EAAE,CAAC;YAC1D,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,cAAc,GAAG,IAAI,CAAC;QAC1B,CAAC;QAED,iHAAiH;QACjH,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;QAExC,KAAK,CAAC,YAAY,EAAE,CAAC;IACzB,CAAC;IAIO,kBAAkB,CAAC,cAAuB,EAAE,mBAA4B,KAAK;QACjF,MAAM,gCAAgC,GAAG,IAAI,CAAC,yBAAyB,IAAI,CAAC,cAAc,CAAC;QAC3F,IAAI,CAAC,yBAAyB,GAAG,cAAc,CAAC;QAEhD,8EAA8E;QAC9E,IAAI,gCAAgC,IAAI,gBAAgB,EAAE,CAAC;YACvD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACpE,IAAI,SAAS,EAAE,WAAW,EAAE,CAAC;gBACzB,sCAAsC;gBACtC,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBAC7C,cAAc,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,aAAa,EAAE,CAAC,SAAS,EAAE,CAAC;gBAE3E,6DAA6D;gBAC7D,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;gBAElE,2HAA2H;gBAC3H,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;oBACjB,wEAAwE;oBACxE,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;oBAEzE,0DAA0D;oBAC1D,IAAI,SAAS,GAAG,OAAO,EAAE,CAAC;wBACtB,oEAAoE;wBACpE,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;wBACvC,8BAA8B,CAC1B,IAAI,CAAC,aAAa,EAClB,SAAS,CAAC,WAAW,EACrB,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAChC,IAAI,CAAC,IAAI,EACT,QAAQ,EACR,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CAC3C,CAAC;wBAEF,kEAAkE;wBAClE,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;oBACnF,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED;;;;OAIG;IACO,mBAAmB,CAAC,WAAoB;QAC9C,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACxD,IAAI,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAC1D,OAAO,eAAe,CAAC;QAC3B,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,oBAAoB,CAAC;QACzD,IAAI,CAAC,WAAW,EAAE,CAAC;YACf,OAAO,eAAe,CAAC;QAC3B,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAClB,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,cAAc,EAAE,CAAC;QAClD,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAErD,uDAAuD;QACvD,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAEnE,sCAAsC;QACtC,MAAM,gBAAgB,GAAG,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAE/I,oEAAoE;QACpE,gBAAgB,CAAC,aAAa,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QAE7D,OAAO,eAAe,CAAC;IAC3B,CAAC;IAEQ,aAAa,CAAC,gBAA0B;QAC7C,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAChD,CAAC;IAEQ,aAAa;QAClB,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;IAChC,CAAC;IAED;;;OAGG;IACa,YAAY;QACxB,OAAO,kBAAkB,CAAC;IAC9B,CAAC;CACJ;AA5gBU;IADN,SAAS,EAAE;yDAC4B;AAkBhC;IADP,kBAAkB,EAAE;iDACoB;AAgBjC;IADP,SAAS,EAAE;8CACa;AAiBjB;IADP,SAAS,EAAE;gDACe;AAsBnB;IADP,SAAS,EAAE;iDACgB;AAqchC,sBAAsB;AACtB,aAAa,CAAC,0BAA0B,EAAE,gBAAgB,CAAC,CAAC;AAE5D;;;;;;;;;;GAUG;AACH,MAAM,UAAU,8BAA8B,CAC1C,GAAW,EACX,KAAa,EACb,MAAe,EACf,oBAA6B,EAC7B,MAAe,EACf,0BAAyE;IAEzE,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACjC,uBAAuB,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,oBAAoB,EAAE,0BAA0B,CAAC,CAAC;IACnG,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAEjC,6CAA6C;IAC7C,0FAA0F;IAC1F,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACjC,KAAK;SACA,QAAQ,CAAC,KAAK,CAAC;SACf,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;SAC3B,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAE/D,4CAA4C;IAC5C,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACjC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAClG,OAAO,MAAM,CAAC,SAAS,EAAE,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,8BAA8B,CAC1C,MAAe,EACf,MAAe,EACf,oBAA6B,EAC7B,UAAkB,EAClB,MAAe,EACf,0BAAyE;IAEzE,gCAAgC;IAChC,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACjC,uBAAuB,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,oBAAoB,EAAE,0BAA0B,CAAC,CAAC;IAEnG,wCAAwC;IACxC,+CAA+C;IAC/C,EAAE;IACF,iEAAiE;IACjE,0BAA0B;IAC1B,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,CAAC,SAAS,CAAC;IAE5B,uDAAuD;IACvD,MAAM,eAAe,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAEzC,wCAAwC;IACxC,yDAAyD;IACzD,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC7C,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAErD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,OAAO,EAAE,CAAC;QAC/B,+DAA+D;QAC/D,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC;QACtB,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC;QACjB,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,oCAAoC;IACpC,MAAM,KAAK,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC;IAExD,mEAAmE;IACnE,oDAAoD;IACpD,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAEvC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC;IACjB,OAAO,MAAM,CAAC;AAClB,CAAC","sourcesContent":["import { GeospatialCameraInputsManager } from \"./geospatialCameraInputsManager\";\r\nimport { Vector3, Matrix, TmpVectors } from \"../Maths/math.vector\";\r\nimport type { Vector2 } from \"../Maths/math.vector\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\nimport { Camera } from \"./camera\";\r\nimport { serialize, serializeAsVector3 } from \"../Misc/decorators\";\r\nimport type { Scene } from \"../scene\";\r\nimport type { MeshPredicate } from \"../Culling/ray.core\";\r\nimport type { DeepImmutable } from \"../types\";\r\nimport { GeospatialLimits } from \"./Limits/geospatialLimits\";\r\nimport { ClampCenterFromPolesInPlace, ComputeLocalBasisToRefs, GeospatialCameraMovement } from \"./geospatialCameraMovement\";\r\nimport type { IVector3Like } from \"../Maths/math.like\";\r\nimport { Vector3CopyToRef, Vector3Distance, Vector3Dot, Vector3SubtractToRef } from \"../Maths/math.vector.functions\";\r\nimport { Clamp, NormalizeRadians } from \"../Maths/math.scalar.functions\";\r\nimport type { AllowedAnimValue } from \"../Behaviors/Cameras/interpolatingBehavior\";\r\nimport { InterpolatingBehavior } from \"../Behaviors/Cameras/interpolatingBehavior\";\r\nimport type { Collider } from \"../Collisions/collider\";\r\nimport type { EasingFunction } from \"../Animations/easing\";\r\nimport type { Animation } from \"../Animations/animation\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\n\r\nexport type GeospatialCameraOptions = {\r\n /**\r\n * Radius of the planet being orbited\r\n */\r\n planetRadius: number;\r\n /**\r\n * If supplied, will be used by the movement class when picking the globe. Can later update camera.movement.pickPredicate directly\r\n */\r\n pickPredicate?: MeshPredicate;\r\n};\r\n\r\n/**\r\n * Camera equipped to orbit a spherical planet centered at world origin\r\n */\r\nexport class GeospatialCamera extends Camera {\r\n override inputs: GeospatialCameraInputsManager;\r\n\r\n /** Movement controller that turns input pixelDeltas into currentFrameDeltas used by camera*/\r\n public readonly movement: GeospatialCameraMovement;\r\n\r\n // Temp vars\r\n private _tempPosition: Vector3 = new Vector3();\r\n private _tempCenter: Vector3 = new Vector3();\r\n\r\n private _viewMatrix = new Matrix();\r\n private _isViewMatrixDirty: boolean;\r\n private _lookAtVector: Vector3 = new Vector3();\r\n\r\n /** Behavior used for smooth flying animations */\r\n private _flyingBehavior: InterpolatingBehavior<GeospatialCamera>;\r\n private _flyToTargets: Map<keyof GeospatialCamera, AllowedAnimValue> = new Map();\r\n\r\n // Collision properties\r\n private _collider?: Collider;\r\n private _collisionVelocity: Vector3 = new Vector3();\r\n /** Public option to customize the collision offset applied each frame - vs the one calculated using internal CollisionCoordinator */\r\n public perFrameCollisionOffset: Vector3 = new Vector3();\r\n /** Enable or disable collision checking for this camera. Default is false. */\r\n @serialize()\r\n public checkCollisions: boolean = false;\r\n\r\n constructor(name: string, scene: Scene, options: GeospatialCameraOptions) {\r\n super(name, new Vector3(), scene);\r\n\r\n this._limits = new GeospatialLimits(options.planetRadius);\r\n\r\n this._flyingBehavior = new InterpolatingBehavior();\r\n this.addBehavior(this._flyingBehavior);\r\n\r\n this.movement = new GeospatialCameraMovement(scene, this._limits, this.position, this.center, this._lookAtVector, options.pickPredicate, this._flyingBehavior);\r\n this._resetToDefault(this._limits);\r\n\r\n this.inputs = new GeospatialCameraInputsManager(this);\r\n this.inputs.addMouse().addMouseWheel().addKeyboard();\r\n }\r\n\r\n @serializeAsVector3()\r\n private _center: Vector3 = new Vector3();\r\n /** The point on the globe that we are anchoring around. If no alternate rotation point is supplied, this will represent the center of screen*/\r\n public get center(): Vector3 {\r\n return this._center;\r\n }\r\n\r\n /**\r\n * Sets the camera position to orbit around a new center point\r\n * @param center The world position (ECEF) to orbit around\r\n */\r\n public set center(center: IVector3Like) {\r\n this._center.copyFromFloats(center.x, center.y, center.z);\r\n this._setOrientation(this._yaw, this._pitch, this._radius, this._center);\r\n }\r\n\r\n @serialize()\r\n private _yaw: number = 0;\r\n /**\r\n * Gets the camera's yaw (rotation around the geocentric normal) in radians\r\n */\r\n public get yaw(): number {\r\n return this._yaw;\r\n }\r\n\r\n /**\r\n * Sets the camera's yaw (rotation around the geocentric normal). Will wrap value to [-π, π)\r\n * @param yaw The desired yaw angle in radians (0 = north, π/2 = east)\r\n */\r\n public set yaw(yaw: number) {\r\n yaw !== this._yaw && this._setOrientation(yaw, this.pitch, this.radius, this.center);\r\n }\r\n\r\n @serialize()\r\n private _pitch: number = 0;\r\n\r\n /**\r\n * Gets the camera's pitch (angle from looking straight at globe)\r\n * Pitch is measured from looking straight down at planet center:\r\n * - zero pitch = looking straight at planet center (down)\r\n * - positive pitch = tilting up away from planet\r\n * - π/2 pitch = looking at horizon (perpendicular to geocentric normal)\r\n */\r\n public get pitch(): number {\r\n return this._pitch;\r\n }\r\n\r\n /**\r\n * Sets the camera's pitch (angle from looking straight at globe). Will wrap value to [-π, π)\r\n * @param pitch The desired pitch angle in radians (0 = looking at planet center, π/2 = looking at horizon)\r\n */\r\n public set pitch(pitch: number) {\r\n pitch !== this._pitch && this._setOrientation(this.yaw, pitch, this.radius, this.center);\r\n }\r\n\r\n @serialize()\r\n private _radius: number = 0;\r\n public get radius(): number {\r\n return this._radius;\r\n }\r\n\r\n /**\r\n * Sets the camera's distance from the current center point\r\n * @param radius The desired radius\r\n */\r\n public set radius(radius: number) {\r\n radius !== this._radius && this._setOrientation(this.yaw, this.pitch, radius, this.center);\r\n }\r\n\r\n protected _checkLimits() {\r\n const limits = this.limits;\r\n this._yaw = Clamp(this._yaw, limits.yawMin, limits.yawMax);\r\n const effectivePitchMax = limits.getEffectivePitchMax(this._radius);\r\n this._pitch = Clamp(this._pitch, limits.pitchMin, effectivePitchMax);\r\n this._radius = Clamp(this._radius, limits.radiusMin, limits.radiusMax);\r\n ClampCenterFromPolesInPlace(this._center);\r\n }\r\n\r\n private _tempVect = new Vector3();\r\n private _tempEast = new Vector3();\r\n private _tempNorth = new Vector3();\r\n private _tempUp = new Vector3();\r\n\r\n private _setOrientation(yaw: number, pitch: number, radius: number, center: DeepImmutable<IVector3Like>): void {\r\n // Wrap yaw and pitch to [-π, π)\r\n this._yaw = NormalizeRadians(yaw);\r\n this._pitch = NormalizeRadians(pitch);\r\n this._radius = radius;\r\n\r\n Vector3CopyToRef(center, this._center);\r\n\r\n // Clamp to limits\r\n this._checkLimits();\r\n\r\n // Refresh local basis at center (treat these as read-only for the whole call)\r\n ComputeLocalBasisToRefs(this._center, this._tempEast, this._tempNorth, this._tempUp, this._scene.useRightHandedSystem, this.movement.calculateUpVectorFromPoint);\r\n\r\n // Compute lookAt from yaw/pitch\r\n ComputeLookAtFromYawPitchToRef(this._yaw, this._pitch, this._center, this._scene.useRightHandedSystem, this._lookAtVector, this.movement.calculateUpVectorFromPoint);\r\n\r\n // Build an orthonormal up aligned with geocentric Up\r\n // When looking straight down (pitch ≈ 0), lookAt is parallel to Up, so use the horizontal direction as the camera's up.\r\n const right = TmpVectors.Vector3[10];\r\n Vector3.CrossToRef(this._tempUp, this._lookAtVector, right);\r\n if (right.lengthSquared() < Epsilon) {\r\n // horiz = north * cos(yaw) + east * sin(yaw)\r\n // Using tempEast directly ensures handedness is taken into account\r\n const horiz = TmpVectors.Vector3[11];\r\n const t1 = TmpVectors.Vector3[12];\r\n horiz\r\n .copyFrom(this._tempNorth)\r\n .scaleInPlace(Math.cos(this._yaw))\r\n .addInPlace(t1.copyFrom(this._tempEast).scaleInPlace(Math.sin(this._yaw)));\r\n // right = cross(horiz, lookAt)\r\n Vector3.CrossToRef(horiz, this._lookAtVector, right);\r\n }\r\n right.normalize();\r\n\r\n // up = normalize(cross(look, right))\r\n Vector3.CrossToRef(this._lookAtVector, right, this.upVector);\r\n this.upVector.normalize();\r\n\r\n // Position = center - look * radius (preserve unit look)\r\n this._tempVect.copyFrom(this._lookAtVector).scaleInPlace(-this._radius);\r\n this._tempPosition.copyFrom(this._center).addInPlace(this._tempVect);\r\n\r\n // Recalculate collisionOffset to be applied later when viewMatrix is calculated (allowing camera users to modify the value in afterCheckInputsObservable)\r\n if (this.checkCollisions) {\r\n this.perFrameCollisionOffset = this._getCollisionOffset(this._tempPosition);\r\n }\r\n\r\n this._position.copyFrom(this._tempPosition);\r\n\r\n this._isViewMatrixDirty = true;\r\n }\r\n\r\n /**\r\n * If camera is actively in flight, will update the target properties and use up the remaining duration from original flyTo call\r\n *\r\n * To start a new flyTo curve entirely, call into flyToAsync again (it will stop the inflight animation)\r\n * @param targetYaw\r\n * @param targetPitch\r\n * @param targetRadius\r\n * @param targetCenter\r\n */\r\n public updateFlyToDestination(targetYaw?: number, targetPitch?: number, targetRadius?: number, targetCenter?: Vector3): void {\r\n this._flyToTargets.clear();\r\n\r\n // For yaw, use shortest path to target.\r\n const deltaYaw = targetYaw !== undefined ? NormalizeRadians(NormalizeRadians(targetYaw) - this._yaw) : 0;\r\n this._flyToTargets.set(\"yaw\", deltaYaw === 0 ? undefined : this._yaw + deltaYaw);\r\n this._flyToTargets.set(\"pitch\", targetPitch != undefined ? NormalizeRadians(targetPitch) : undefined);\r\n this._flyToTargets.set(\"radius\", targetRadius);\r\n this._flyToTargets.set(\"center\", targetCenter?.clone());\r\n\r\n this._flyingBehavior.updateProperties(this._flyToTargets);\r\n }\r\n\r\n /**\r\n * Animate camera towards passed in property values. If undefined, will use current value\r\n * @param targetYaw\r\n * @param targetPitch\r\n * @param targetRadius\r\n * @param targetCenter\r\n * @param flightDurationMs\r\n * @param easingFunction\r\n * @param centerHopScale If supplied, will define the parabolic hop height scale for center animation to create a \"bounce\" effect\r\n * @returns Promise that will return when the animation is complete (or interuppted by pointer input)\r\n */\r\n public async flyToAsync(\r\n targetYaw?: number,\r\n targetPitch?: number,\r\n targetRadius?: number,\r\n targetCenter?: Vector3,\r\n flightDurationMs: number = 1000,\r\n easingFunction?: EasingFunction,\r\n centerHopScale?: number\r\n ): Promise<void> {\r\n this._flyToTargets.clear();\r\n\r\n // For yaw, use shortest path to target.\r\n const deltaYaw = targetYaw !== undefined ? NormalizeRadians(NormalizeRadians(targetYaw) - this._yaw) : 0;\r\n this._flyToTargets.set(\"yaw\", deltaYaw === 0 ? undefined : this._yaw + deltaYaw);\r\n this._flyToTargets.set(\"pitch\", targetPitch !== undefined ? NormalizeRadians(targetPitch) : undefined);\r\n this._flyToTargets.set(\"radius\", targetRadius);\r\n this._flyToTargets.set(\"center\", targetCenter?.clone());\r\n\r\n let overrideAnimationFunction;\r\n if (targetCenter !== undefined && !targetCenter.equals(this.center)) {\r\n // Animate center directly with custom interpolation\r\n overrideAnimationFunction = (key: string, animation: Animation): void => {\r\n if (key === \"center\") {\r\n // Override the Vector3 interpolation to use SLERP + hop\r\n animation.vector3InterpolateFunction = (startValue, endValue, gradient) => {\r\n // gradient is the eased value (0 to 1) after easing function is applied\r\n\r\n // Slerp between start and end\r\n const newCenter = Vector3.SlerpToRef(startValue, endValue, gradient, this._tempCenter);\r\n\r\n // Apply parabolic hop if requested\r\n if (centerHopScale && centerHopScale > 0) {\r\n // Parabolic formula: peaks at t=0.5, returns to 0 at gradient=0 and gradient=1\r\n // if hopPeakT = .5 the denominator would be hopPeakT * hopPeakT - hopPeakT, which = -.25\r\n const hopPeakOffset = centerHopScale * Vector3Distance(startValue, endValue);\r\n const hopOffset = hopPeakOffset * Clamp((gradient * gradient - gradient) / -0.25);\r\n // Scale the center outward (away from origin)\r\n newCenter.scaleInPlace(1 + hopOffset / newCenter.length());\r\n }\r\n\r\n return newCenter;\r\n };\r\n }\r\n };\r\n }\r\n\r\n return await this._flyingBehavior.animatePropertiesAsync(this._flyToTargets, flightDurationMs, easingFunction, overrideAnimationFunction);\r\n }\r\n\r\n /**\r\n * Helper function to move camera towards a given point by `distanceScale` of the current camera-to-destination distance (by default 50%).\r\n * @param destination point to move towards\r\n * @param distanceScale value between 0 and 1, % of distance to move\r\n * @param durationMs duration of flight, default 1s\r\n * @param easingFn optional easing function for flight interpolation of properties\r\n * @param centerHopScale If supplied, will define the parabolic hop height scale for center animation to create a \"bounce\" effect\r\n */\r\n public async flyToPointAsync(destination: Vector3, distanceScale: number = 0.5, durationMs: number = 1000, easingFn?: EasingFunction, centerHopScale?: number) {\r\n // Move by a fraction of the camera-to-destination distance\r\n const zoomDistance = Vector3Distance(this.position, destination) * distanceScale;\r\n const newRadius = this._getCenterAndRadiusFromZoomToPoint(destination, zoomDistance, this._tempCenter);\r\n await this.flyToAsync(undefined, undefined, newRadius, this._tempCenter, durationMs, easingFn, centerHopScale);\r\n !this.isDisposed() && this._recalculateCenter(false, true /** force */);\r\n }\r\n\r\n private _limits: GeospatialLimits;\r\n public get limits(): GeospatialLimits {\r\n return this._limits;\r\n }\r\n\r\n private _resetToDefault(limits: GeospatialLimits): void {\r\n // Camera configuration vars\r\n const restingAltitude = limits.radiusMax !== Infinity ? limits.radiusMax : limits.planetRadius * 4;\r\n this.position.copyFromFloats(restingAltitude, 0, 0);\r\n this._center.copyFromFloats(limits.planetRadius, 0, 0);\r\n this._radius = Vector3.Distance(this.position, this.center);\r\n\r\n // Temp vars\r\n this._tempPosition = new Vector3();\r\n\r\n // View matrix calculation vars\r\n this._viewMatrix = Matrix.Identity();\r\n this._center.subtractToRef(this._position, this._lookAtVector).normalize(); // Lookat vector of the camera\r\n this.upVector = Vector3.Up(); // Up vector of the camera (does work for -X look at)\r\n this._isViewMatrixDirty = true;\r\n\r\n this._setOrientation(this._yaw, this._pitch, this._radius, this._center);\r\n }\r\n\r\n /** @internal */\r\n override _getViewMatrix() {\r\n if (!this._isViewMatrixDirty) {\r\n return this._viewMatrix;\r\n }\r\n this._isViewMatrixDirty = false;\r\n\r\n // Ensure vectors are normalized\r\n this.upVector.normalize();\r\n this._lookAtVector.normalize();\r\n\r\n // Apply the same offset to both position and center to preserve orbital relationship\r\n // This keeps yaw/pitch/radius intact - just lifts the whole \"rig\"\r\n this._position.addInPlace(this.perFrameCollisionOffset);\r\n this._center.addInPlace(this.perFrameCollisionOffset);\r\n\r\n // Calculate view matrix with camera position and center\r\n if (this.getScene().useRightHandedSystem) {\r\n Matrix.LookAtRHToRef(this.position, this._center, this.upVector, this._viewMatrix);\r\n } else {\r\n Matrix.LookAtLHToRef(this.position, this._center, this.upVector, this._viewMatrix);\r\n }\r\n\r\n return this._viewMatrix;\r\n }\r\n\r\n /** @internal */\r\n override _isSynchronizedViewMatrix(): boolean {\r\n if (!super._isSynchronizedViewMatrix() || this._isViewMatrixDirty) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n private _applyGeocentricTranslation() {\r\n // Store pending position (without any corrections applied)\r\n this.center.addToRef(this.movement.panDeltaCurrentFrame, this._tempPosition);\r\n\r\n if (!this.movement.isInterpolating) {\r\n // Calculate the position correction to keep camera at the same radius when applying translation\r\n this._tempPosition.normalize().scaleInPlace(this.center.length());\r\n }\r\n // Set center which will call _setOrientation\r\n this.center = this._tempPosition;\r\n }\r\n\r\n /**\r\n * This rotation keeps the camera oriented towards the globe as it orbits around it. This is different from cameraCentricRotation which is when the camera rotates around its own axis\r\n */\r\n private _applyGeocentricRotation(): void {\r\n const rotationDeltaCurrentFrame = this.movement.rotationDeltaCurrentFrame;\r\n if (rotationDeltaCurrentFrame.x !== 0 || rotationDeltaCurrentFrame.y !== 0) {\r\n const pitch = rotationDeltaCurrentFrame.x !== 0 ? Clamp(this._pitch + rotationDeltaCurrentFrame.x, 0, 0.5 * Math.PI - Epsilon) : this._pitch;\r\n const yaw = rotationDeltaCurrentFrame.y !== 0 ? this._yaw + rotationDeltaCurrentFrame.y : this._yaw;\r\n\r\n this._setOrientation(yaw, pitch, this._radius, this._center);\r\n }\r\n }\r\n\r\n private _getCenterAndRadiusFromZoomToPoint(targetPoint: DeepImmutable<IVector3Like>, distance: number, newCenterResult: Vector3): number {\r\n const directionToTarget = Vector3SubtractToRef(targetPoint, this._position, TmpVectors.Vector3[0]);\r\n const distanceToTarget = directionToTarget.length();\r\n\r\n // Don't zoom past the min radius limit.\r\n if (distanceToTarget < this.limits.radiusMin) {\r\n newCenterResult.copyFrom(this._center);\r\n const requestedRadius = this._radius - distance;\r\n const newRadius = Clamp(requestedRadius, this.limits.radiusMin, this.limits.radiusMax);\r\n return newRadius;\r\n }\r\n\r\n // Move the camera position towards targetPoint by distanceToTarget\r\n directionToTarget.scaleInPlace(distance / distanceToTarget);\r\n const newPosition = this._position.addToRef(directionToTarget, TmpVectors.Vector3[1]);\r\n\r\n // Project the movement onto the look vector to derive the new center/radius.\r\n const projectedDistance = Vector3Dot(directionToTarget, this._lookAtVector);\r\n const newRadius = this._radius - projectedDistance;\r\n const newRadiusClamped = Clamp(newRadius, this.limits.radiusMin, this.limits.radiusMax);\r\n newCenterResult.copyFrom(newPosition).addInPlace(this._lookAtVector.scale(newRadiusClamped));\r\n\r\n return newRadiusClamped;\r\n }\r\n\r\n /**\r\n * Apply zoom by moving the camera toward/away from a target point.\r\n */\r\n private _applyZoom() {\r\n let zoomDelta = this.movement.zoomDeltaCurrentFrame;\r\n const pickedPoint = this.movement.computedPerFrameZoomPickPoint;\r\n\r\n // Clamp zoom delta to limits before applying\r\n zoomDelta = this._clampZoomDelta(zoomDelta, pickedPoint);\r\n\r\n if (Math.abs(zoomDelta) < Epsilon) {\r\n return;\r\n }\r\n if (pickedPoint) {\r\n // Zoom toward the picked point under cursor\r\n this.zoomToPoint(pickedPoint, zoomDelta);\r\n } else {\r\n // Zoom along lookAt vector (fallback when no surface under cursor)\r\n this.zoomAlongLookAt(zoomDelta);\r\n }\r\n }\r\n\r\n private _clampZoomDelta(zoomDelta: number, pickedPoint?: Vector3): number {\r\n if (Math.abs(zoomDelta) < Epsilon) {\r\n return 0;\r\n }\r\n\r\n const distanceToTarget = pickedPoint ? Vector3Distance(this._position, pickedPoint) : undefined;\r\n return this.limits.clampZoomDistance(zoomDelta, this._radius, distanceToTarget);\r\n }\r\n\r\n public zoomToPoint(targetPoint: DeepImmutable<IVector3Like>, distance: number) {\r\n const newRadius = this._getCenterAndRadiusFromZoomToPoint(targetPoint, distance, this._tempCenter);\r\n // Apply the new orientation\r\n this._setOrientation(this._yaw, this._pitch, newRadius, this._tempCenter);\r\n }\r\n\r\n public zoomAlongLookAt(distance: number) {\r\n // Clamp radius to limits\r\n const requestedRadius = this._radius - distance;\r\n const newRadius = Clamp(requestedRadius, this.limits.radiusMin, this.limits.radiusMax);\r\n\r\n // Simply change radius without moving center\r\n this._setOrientation(this._yaw, this._pitch, newRadius, this._center);\r\n }\r\n\r\n override _checkInputs(): void {\r\n this.inputs.checkInputs();\r\n this.perFrameCollisionOffset.setAll(0);\r\n\r\n // Let movement class handle all per-frame logic\r\n this.movement.computeCurrentFrameDeltas();\r\n\r\n let isCenterMoving = false;\r\n if (this.movement.panDeltaCurrentFrame.lengthSquared() > 0) {\r\n this._applyGeocentricTranslation();\r\n // After a drag, recalculate the center point to ensure it's still on the surface.\r\n isCenterMoving = true;\r\n }\r\n if (this.movement.rotationDeltaCurrentFrame.lengthSquared() > 0) {\r\n this._applyGeocentricRotation();\r\n }\r\n\r\n if (Math.abs(this.movement.zoomDeltaCurrentFrame) > Epsilon) {\r\n this._applyZoom();\r\n isCenterMoving = true;\r\n }\r\n\r\n // After a movement impacting center or radius, recalculate the center point to ensure it's still on the surface.\r\n this._recalculateCenter(isCenterMoving);\r\n\r\n super._checkInputs();\r\n }\r\n\r\n private _wasCenterMovingLastFrame = false;\r\n\r\n private _recalculateCenter(isCenterMoving: boolean, forceRecalculate: boolean = false): void {\r\n const shouldRecalculateCenterAfterMove = this._wasCenterMovingLastFrame && !isCenterMoving;\r\n this._wasCenterMovingLastFrame = isCenterMoving;\r\n\r\n // Wait until movement impacting center is complete to avoid wasted raycasting\r\n if (shouldRecalculateCenterAfterMove || forceRecalculate) {\r\n const newCenter = this.movement.pickAlongVector(this._lookAtVector);\r\n if (newCenter?.pickedPoint) {\r\n // Direction from new center to origin\r\n const centerToOrigin = TmpVectors.Vector3[4];\r\n centerToOrigin.copyFrom(newCenter.pickedPoint).negateInPlace().normalize();\r\n\r\n // Check if this direction aligns with camera's lookAt vector\r\n const dotProduct = Vector3Dot(this._lookAtVector, centerToOrigin);\r\n\r\n // Only update if the center is looking toward the origin (dot product > 0) to avoid a center on the opposite side of globe\r\n if (dotProduct > 0) {\r\n // Compute the new radius as distance from camera position to new center\r\n const newRadius = Vector3Distance(this._position, newCenter.pickedPoint);\r\n\r\n // Only update if the new center is in front of the camera\r\n if (newRadius > Epsilon) {\r\n // Compute yaw/pitch that correspond to current lookAt at new center\r\n const yawPitch = TmpVectors.Vector2[0];\r\n ComputeYawPitchFromLookAtToRef(\r\n this._lookAtVector,\r\n newCenter.pickedPoint,\r\n this._scene.useRightHandedSystem,\r\n this._yaw,\r\n yawPitch,\r\n this.movement.calculateUpVectorFromPoint\r\n );\r\n\r\n // Call _setOrientation with the computed yaw/pitch and new center\r\n this._setOrientation(yawPitch.x, yawPitch.y, newRadius, newCenter.pickedPoint);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Allows extended classes to override how collision offset is calculated\r\n * @param newPosition\r\n * @returns\r\n */\r\n protected _getCollisionOffset(newPosition: Vector3): Vector3 {\r\n const collisionOffset = TmpVectors.Vector3[6].setAll(0);\r\n if (!this.checkCollisions || !this._scene.collisionsEnabled) {\r\n return collisionOffset;\r\n }\r\n\r\n const coordinator = this.getScene().collisionCoordinator;\r\n if (!coordinator) {\r\n return collisionOffset;\r\n }\r\n\r\n if (!this._collider) {\r\n this._collider = coordinator.createCollider();\r\n }\r\n this._collider._radius.setAll(this.limits.radiusMin);\r\n\r\n // Calculate velocity from old position to new position\r\n newPosition.subtractToRef(this._position, this._collisionVelocity);\r\n\r\n // Get the collision-adjusted position\r\n const adjustedPosition = coordinator.getNewPosition(this._position, this._collisionVelocity, this._collider, 3, null, () => {}, this.uniqueId);\r\n\r\n // Calculate the collision offset (how much the position was pushed)\r\n adjustedPosition.subtractToRef(newPosition, collisionOffset);\r\n\r\n return collisionOffset;\r\n }\r\n\r\n override attachControl(noPreventDefault?: boolean): void {\r\n this.inputs.attachElement(noPreventDefault);\r\n }\r\n\r\n override detachControl(): void {\r\n this.inputs.detachElement();\r\n }\r\n\r\n /**\r\n * Gets the class name of the camera.\r\n * @returns the class name\r\n */\r\n public override getClassName(): string {\r\n return \"GeospatialCamera\";\r\n }\r\n}\r\n\r\n// Register Class Name\r\nRegisterClass(\"BABYLON.GeospatialCamera\", GeospatialCamera);\r\n\r\n/**\r\n * Compute the lookAt direction vector from yaw and pitch angles at a given center point.\r\n * This is the forward formula used by GeospatialCamera._setOrientation.\r\n * @param yaw - The yaw angle in radians (0 = north, π/2 = east)\r\n * @param pitch - The pitch angle in radians (0 = looking at planet center, π/2 = looking at horizon)\r\n * @param center - The center point on the globe\r\n * @param useRightHandedSystem - Whether the scene uses a right-handed coordinate system\r\n * @param result - The vector to store the result in\r\n * @param calculateUpVectorFromPoint - Optional function to calculate the up vector from a point, allowing for non-spherical planets. If not supplied, a perfect sphere is assumed and the up vector is just the normalized center point.\r\n * @returns The normalized lookAt direction vector (same as result)\r\n */\r\nexport function ComputeLookAtFromYawPitchToRef(\r\n yaw: number,\r\n pitch: number,\r\n center: Vector3,\r\n useRightHandedSystem: boolean,\r\n result: Vector3,\r\n calculateUpVectorFromPoint?: (point: Vector3, result: Vector3) => Vector3\r\n): Vector3 {\r\n const east = TmpVectors.Vector3[0];\r\n const north = TmpVectors.Vector3[1];\r\n const up = TmpVectors.Vector3[2];\r\n ComputeLocalBasisToRefs(center, east, north, up, useRightHandedSystem, calculateUpVectorFromPoint);\r\n const sinPitch = Math.sin(pitch);\r\n const cosPitch = Math.cos(pitch);\r\n\r\n // horiz = north * cos(yaw) + east * sin(yaw)\r\n // Handedness is taken into account when defining east vector via ComputeLocalBasisToRefs.\r\n const horiz = TmpVectors.Vector3[3];\r\n const t1 = TmpVectors.Vector3[4];\r\n horiz\r\n .copyFrom(north)\r\n .scaleInPlace(Math.cos(yaw))\r\n .addInPlace(t1.copyFrom(east).scaleInPlace(Math.sin(yaw)));\r\n\r\n // lookAt = horiz * sinPitch - up * cosPitch\r\n const t2 = TmpVectors.Vector3[5];\r\n result.copyFrom(horiz).scaleInPlace(sinPitch).addInPlace(t2.copyFrom(up).scaleInPlace(-cosPitch));\r\n return result.normalize();\r\n}\r\n\r\n/**\r\n * Given a lookAt direction and center, compute the yaw and pitch angles that would produce that lookAt.\r\n * This is the inverse of ComputeLookAtFromYawPitchToRef.\r\n * @param lookAt - The normalized lookAt direction vector\r\n * @param center - The center point on the globe\r\n * @param useRightHandedSystem - Whether the scene uses a right-handed coordinate system\r\n * @param currentYaw - The current yaw value to use as fallback when pitch is near 0 (looking straight down/up)\r\n * @param result - The Vector2 to store the result in (x = yaw, y = pitch)\r\n * @param calculateUpVectorFromPoint - Optional function to calculate the up vector from a point. If supplied, this function will be used instead of assuming a spherical geocentric normal, allowing support for non-spherical planets or custom up vector logic.\r\n * @returns The result Vector2\r\n */\r\nexport function ComputeYawPitchFromLookAtToRef(\r\n lookAt: Vector3,\r\n center: Vector3,\r\n useRightHandedSystem: boolean,\r\n currentYaw: number,\r\n result: Vector2,\r\n calculateUpVectorFromPoint?: (point: Vector3, result: Vector3) => Vector3\r\n): Vector2 {\r\n // Compute local basis at center\r\n const east = TmpVectors.Vector3[6];\r\n const north = TmpVectors.Vector3[7];\r\n const up = TmpVectors.Vector3[8];\r\n ComputeLocalBasisToRefs(center, east, north, up, useRightHandedSystem, calculateUpVectorFromPoint);\r\n\r\n // lookAt = horiz*sinPitch - up*cosPitch\r\n // where horiz = north*cos(yaw) + east*sin(yaw)\r\n //\r\n // The vertical component of lookAt (along up) gives us cosPitch:\r\n // lookAt · up = -cosPitch\r\n const lookDotUp = Vector3Dot(lookAt, up);\r\n const cosPitch = -lookDotUp;\r\n\r\n // Clamp cosPitch to valid range to avoid NaN from acos\r\n const clampedCosPitch = Clamp(cosPitch, -1, 1);\r\n const pitch = Math.acos(clampedCosPitch);\r\n\r\n // The horizontal component gives us yaw\r\n // lookHorizontal = lookAt + up*cosPitch = horiz*sinPitch\r\n const lookHorizontal = TmpVectors.Vector3[9];\r\n const scaledUp = TmpVectors.Vector3[10];\r\n scaledUp.copyFrom(up).scaleInPlace(cosPitch);\r\n lookHorizontal.copyFrom(lookAt).addInPlace(scaledUp);\r\n\r\n const sinPitch = Math.sin(pitch);\r\n if (Math.abs(sinPitch) < Epsilon) {\r\n // Looking straight down or up, yaw is undefined - keep current\r\n result.x = currentYaw;\r\n result.y = pitch;\r\n return result;\r\n }\r\n\r\n // horiz = lookHorizontal / sinPitch\r\n const horiz = lookHorizontal.scaleInPlace(1 / sinPitch);\r\n\r\n // From the forward formula: horiz = North*cos(yaw) + East*sin(yaw)\r\n // So: cosYaw = horiz · north, sinYaw = horiz · east\r\n const cosYaw = Vector3Dot(horiz, north);\r\n const sinYaw = Vector3Dot(horiz, east);\r\n\r\n result.x = Math.atan2(sinYaw, cosYaw);\r\n result.y = pitch;\r\n return result;\r\n}\r\n"]}
@@ -36,6 +36,15 @@ export declare class GeospatialCameraMovement extends CameraMovement {
36
36
  private _dragPlaneHitPointLocal;
37
37
  private _previousDragPlaneHitPointLocal;
38
38
  constructor(scene: Scene, limits: GeospatialLimits, cameraPosition: Vector3, _cameraCenter: Vector3, _cameraLookAt: Vector3, pickPredicate?: MeshPredicate, behavior?: InterpolatingBehavior<GeospatialCamera>);
39
+ /**
40
+ * Function to calculate the up vector from a given point.
41
+ * Can be overridden to support non-spherical planets or custom up vector logic.
42
+ * Defaults to using the geocentric normal.
43
+ * @param point The point from which to calculate the up vector (e.g., camera position)
44
+ * @param result The vector to store the calculated up vector
45
+ * @returns The calculated up vector
46
+ */
47
+ calculateUpVectorFromPoint(point: Vector3, result: Vector3): Vector3;
39
48
  startDrag(pointerX: number, pointerY: number): void;
40
49
  stopDrag(): void;
41
50
  /**
@@ -64,6 +73,7 @@ export declare function ClampCenterFromPolesInPlace(center: Vector3): Vector3;
64
73
  * @param refNorth - Receives the north direction
65
74
  * @param refUp - Receives the up (outward) direction
66
75
  * @param useRightHandedSystem - Whether the scene uses a right-handed coordinate system (default: false)
76
+ * @param calculateUpVectorFromPoint - Optional function to calculate the up vector from a point. If supplied, this function will be used instead of assuming a spherical geocentric normal, allowing support for non-spherical planets or custom up vector logic.
67
77
  * @internal
68
78
  */
69
- export declare function ComputeLocalBasisToRefs(worldPos: Vector3, refEast: Vector3, refNorth: Vector3, refUp: Vector3, useRightHandedSystem?: boolean): void;
79
+ export declare function ComputeLocalBasisToRefs(worldPos: Vector3, refEast: Vector3, refNorth: Vector3, refUp: Vector3, useRightHandedSystem?: boolean, calculateUpVectorFromPoint?: (point: Vector3, result: Vector3) => Vector3): void;
@@ -38,6 +38,17 @@ export class GeospatialCameraMovement extends CameraMovement {
38
38
  this.rotationYSpeed = Math.PI / 500; // Move 1/500th of a half circle per pixel
39
39
  this.zoomSpeed = 2; // Base zoom speed; actual speed is scaled based on altitude
40
40
  }
41
+ /**
42
+ * Function to calculate the up vector from a given point.
43
+ * Can be overridden to support non-spherical planets or custom up vector logic.
44
+ * Defaults to using the geocentric normal.
45
+ * @param point The point from which to calculate the up vector (e.g., camera position)
46
+ * @param result The vector to store the calculated up vector
47
+ * @returns The calculated up vector
48
+ */
49
+ calculateUpVectorFromPoint(point, result) {
50
+ return point.normalizeToRef(result);
51
+ }
41
52
  startDrag(pointerX, pointerY) {
42
53
  const pickResult = this._scene.pick(pointerX, pointerY, this.pickPredicate);
43
54
  if (pickResult.pickedPoint && pickResult.ray) {
@@ -62,10 +73,10 @@ export class GeospatialCameraMovement extends CameraMovement {
62
73
  */
63
74
  _recalculateDragPlaneHitPoint(hitPointRadius, ray, localToEcefResult) {
64
75
  // Use the camera's geocentric normal to find the dragPlaneOriginPoint which lives at hitPointRadius along the camera's geocentric normal
65
- this._cameraPosition.normalizeToRef(this._dragPlaneNormal);
76
+ this.calculateUpVectorFromPoint(this._cameraPosition, this._dragPlaneNormal);
66
77
  this._dragPlaneNormal.scaleToRef(hitPointRadius, this._dragPlaneOriginPointEcef);
67
78
  // The dragPlaneOffsetVector will later be recalculated when drag occurs, and the delta between the offset vectors will be applied to localTranslation
68
- ComputeLocalBasisToRefs(this._dragPlaneOriginPointEcef, TmpVectors.Vector3[0], TmpVectors.Vector3[1], TmpVectors.Vector3[2], this._scene.useRightHandedSystem);
79
+ ComputeLocalBasisToRefs(this._dragPlaneOriginPointEcef, TmpVectors.Vector3[0], TmpVectors.Vector3[1], TmpVectors.Vector3[2], this._scene.useRightHandedSystem, this.calculateUpVectorFromPoint);
69
80
  const localToEcef = Matrix.FromXYZAxesToRef(TmpVectors.Vector3[0], TmpVectors.Vector3[1], TmpVectors.Vector3[2], localToEcefResult);
70
81
  localToEcef.setTranslationFromFloats(this._dragPlaneOriginPointEcef.x, this._dragPlaneOriginPointEcef.y, this._dragPlaneOriginPointEcef.z);
71
82
  const ecefToLocal = localToEcef.invertToRef(TmpVectors.Matrix[1]);
@@ -106,7 +117,10 @@ export class GeospatialCameraMovement extends CameraMovement {
106
117
  const centerRadius = cameraCenter.length(); // distance from planet origin to camera center
107
118
  const currentRadius = this._cameraPosition.length();
108
119
  // Dampen the pan speed based on latitude (slower near poles)
109
- const sineOfSphericalLat = centerRadius === 0 ? 0 : cameraCenter.z / centerRadius;
120
+ const upAtCenter = TmpVectors.Vector3[7];
121
+ this.calculateUpVectorFromPoint(cameraCenter, upAtCenter);
122
+ // Latitude is derived from the Z component of the up vector (ECEF convention: Z = polar axis)
123
+ const sineOfSphericalLat = upAtCenter.z;
110
124
  const cosOfSphericalLat = Math.sqrt(1 - Math.min(1, sineOfSphericalLat * sineOfSphericalLat));
111
125
  const latitudeDampening = Math.sqrt(Math.abs(cosOfSphericalLat)); // sqrt here reduces effect near equator
112
126
  // Reduce the dampening effect near surface (so that at ground level, pan speed is not affected by latitude)
@@ -191,11 +205,17 @@ function IntersectRayWithPlaneToRef(ray, plane, ref) {
191
205
  * @param refNorth - Receives the north direction
192
206
  * @param refUp - Receives the up (outward) direction
193
207
  * @param useRightHandedSystem - Whether the scene uses a right-handed coordinate system (default: false)
208
+ * @param calculateUpVectorFromPoint - Optional function to calculate the up vector from a point. If supplied, this function will be used instead of assuming a spherical geocentric normal, allowing support for non-spherical planets or custom up vector logic.
194
209
  * @internal
195
210
  */
196
- export function ComputeLocalBasisToRefs(worldPos, refEast, refNorth, refUp, useRightHandedSystem = false) {
197
- // up = normalized position (geocentric normal)
198
- refUp.copyFrom(worldPos).normalize();
211
+ export function ComputeLocalBasisToRefs(worldPos, refEast, refNorth, refUp, useRightHandedSystem = false, calculateUpVectorFromPoint) {
212
+ if (calculateUpVectorFromPoint) {
213
+ calculateUpVectorFromPoint(worldPos, refUp);
214
+ }
215
+ else {
216
+ // up = normalized position (geocentric normal)
217
+ refUp.copyFrom(worldPos).normalize();
218
+ }
199
219
  // east – cross product order determines handedness
200
220
  const worldNorth = Vector3.LeftHandedForwardReadOnly; // (0,0,1)
201
221
  if (useRightHandedSystem) {