@babylonjs/core 9.14.0 → 9.15.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 (141) hide show
  1. package/Animations/animationGroup.d.ts +0 -1
  2. package/Animations/animationGroup.js +0 -1
  3. package/Animations/animationGroup.js.map +1 -1
  4. package/Animations/animationGroup.pure.js +2 -0
  5. package/Animations/animationGroup.pure.js.map +1 -1
  6. package/Cameras/Inputs/BaseCameraPointersInput.d.ts +2 -1
  7. package/Cameras/Inputs/BaseCameraPointersInput.js +3 -2
  8. package/Cameras/Inputs/BaseCameraPointersInput.js.map +1 -1
  9. package/Cameras/Inputs/arcRotateCameraKeyboardMoveInput.d.ts +3 -0
  10. package/Cameras/Inputs/arcRotateCameraKeyboardMoveInput.js +37 -10
  11. package/Cameras/Inputs/arcRotateCameraKeyboardMoveInput.js.map +1 -1
  12. package/Cameras/Inputs/flyCameraKeyboardInput.js +19 -9
  13. package/Cameras/Inputs/flyCameraKeyboardInput.js.map +1 -1
  14. package/Cameras/Inputs/freeCameraKeyboardMoveInput.js +21 -18
  15. package/Cameras/Inputs/freeCameraKeyboardMoveInput.js.map +1 -1
  16. package/Cameras/Inputs/geospatialCameraKeyboardInput.d.ts +2 -0
  17. package/Cameras/Inputs/geospatialCameraKeyboardInput.js +31 -12
  18. package/Cameras/Inputs/geospatialCameraKeyboardInput.js.map +1 -1
  19. package/Cameras/Inputs/geospatialCameraPointersInput.d.ts +11 -1
  20. package/Cameras/Inputs/geospatialCameraPointersInput.js +18 -2
  21. package/Cameras/Inputs/geospatialCameraPointersInput.js.map +1 -1
  22. package/Cameras/VR/vrExperienceHelper.d.ts +0 -2
  23. package/Cameras/VR/vrExperienceHelper.js +0 -2
  24. package/Cameras/VR/vrExperienceHelper.js.map +1 -1
  25. package/Cameras/VR/vrExperienceHelper.pure.js +5 -0
  26. package/Cameras/VR/vrExperienceHelper.pure.js.map +1 -1
  27. package/Engines/WebGPU/webgpuClearQuad.pure.js +7 -1
  28. package/Engines/WebGPU/webgpuClearQuad.pure.js.map +1 -1
  29. package/Engines/abstractEngine.pure.js +2 -2
  30. package/Engines/abstractEngine.pure.js.map +1 -1
  31. package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.d.ts +0 -1
  32. package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.js +0 -1
  33. package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.js.map +1 -1
  34. package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.pure.js +3 -0
  35. package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.pure.js.map +1 -1
  36. package/Helpers/environmentHelper.js +2 -2
  37. package/Helpers/environmentHelper.js.map +1 -1
  38. package/Lights/Clustered/clusteredLightContainer.pure.js +13 -0
  39. package/Lights/Clustered/clusteredLightContainer.pure.js.map +1 -1
  40. package/Loading/Plugins/babylonFileLoader.pure.js +3 -3
  41. package/Loading/Plugins/babylonFileLoader.pure.js.map +1 -1
  42. package/Materials/Background/backgroundMaterial.pure.js +3 -1
  43. package/Materials/Background/backgroundMaterial.pure.js.map +1 -1
  44. package/Materials/Node/Blocks/Dual/reflectionTextureBaseBlock.pure.js +2 -2
  45. package/Materials/Node/Blocks/Dual/reflectionTextureBaseBlock.pure.js.map +1 -1
  46. package/Materials/Node/Blocks/PBR/refractionBlock.pure.js +2 -2
  47. package/Materials/Node/Blocks/PBR/refractionBlock.pure.js.map +1 -1
  48. package/Materials/Node/nodeMaterial.pure.js +3 -0
  49. package/Materials/Node/nodeMaterial.pure.js.map +1 -1
  50. package/Materials/Node/nodeMaterialBuildState.d.ts +3 -3
  51. package/Materials/PBR/openpbrMaterial.pure.js +3 -1
  52. package/Materials/PBR/openpbrMaterial.pure.js.map +1 -1
  53. package/Materials/PBR/pbrMaterial.pure.js +3 -0
  54. package/Materials/PBR/pbrMaterial.pure.js.map +1 -1
  55. package/Materials/PBR/pbrMetallicRoughnessMaterial.pure.js +3 -0
  56. package/Materials/PBR/pbrMetallicRoughnessMaterial.pure.js.map +1 -1
  57. package/Materials/PBR/pbrSpecularGlossinessMaterial.pure.js +3 -0
  58. package/Materials/PBR/pbrSpecularGlossinessMaterial.pure.js.map +1 -1
  59. package/Materials/Textures/cubeTexture.d.ts +0 -1
  60. package/Materials/Textures/cubeTexture.js +0 -1
  61. package/Materials/Textures/cubeTexture.js.map +1 -1
  62. package/Materials/Textures/cubeTexture.pure.js +2 -0
  63. package/Materials/Textures/cubeTexture.pure.js.map +1 -1
  64. package/Materials/Textures/dynamicTexture.d.ts +0 -1
  65. package/Materials/Textures/dynamicTexture.js +0 -1
  66. package/Materials/Textures/dynamicTexture.js.map +1 -1
  67. package/Materials/Textures/dynamicTexture.pure.js +2 -0
  68. package/Materials/Textures/dynamicTexture.pure.js.map +1 -1
  69. package/Materials/Textures/htmlElementTexture.d.ts +0 -2
  70. package/Materials/Textures/htmlElementTexture.js +0 -2
  71. package/Materials/Textures/htmlElementTexture.js.map +1 -1
  72. package/Materials/Textures/htmlElementTexture.pure.js +4 -0
  73. package/Materials/Textures/htmlElementTexture.pure.js.map +1 -1
  74. package/Materials/Textures/multiRenderTarget.d.ts +0 -1
  75. package/Materials/Textures/multiRenderTarget.js +0 -1
  76. package/Materials/Textures/multiRenderTarget.js.map +1 -1
  77. package/Materials/Textures/multiRenderTarget.pure.js +2 -0
  78. package/Materials/Textures/multiRenderTarget.pure.js.map +1 -1
  79. package/Materials/standardMaterial.pure.js +3 -1
  80. package/Materials/standardMaterial.pure.js.map +1 -1
  81. package/Misc/decorators.functions.d.ts +7 -0
  82. package/Misc/decorators.functions.js +86 -35
  83. package/Misc/decorators.functions.js.map +1 -1
  84. package/Misc/snapshotRenderingHelper.d.ts +4 -1
  85. package/Misc/snapshotRenderingHelper.js.map +1 -1
  86. package/Misc/symbolMetadataPolyfill.d.ts +11 -0
  87. package/Misc/symbolMetadataPolyfill.js +22 -0
  88. package/Misc/symbolMetadataPolyfill.js.map +1 -0
  89. package/Misc/tools.pure.js +1 -1
  90. package/Misc/tools.pure.js.map +1 -1
  91. package/Particles/gpuParticleSystem.d.ts +0 -1
  92. package/Particles/gpuParticleSystem.js +0 -1
  93. package/Particles/gpuParticleSystem.js.map +1 -1
  94. package/Particles/thinParticleSystem.d.ts +0 -1
  95. package/Particles/thinParticleSystem.js +0 -1
  96. package/Particles/thinParticleSystem.js.map +1 -1
  97. package/Particles/thinParticleSystem.pure.js +2 -0
  98. package/Particles/thinParticleSystem.pure.js.map +1 -1
  99. package/Particles/webgl2ParticleSystem.pure.js +2 -0
  100. package/Particles/webgl2ParticleSystem.pure.js.map +1 -1
  101. package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.d.ts +0 -1
  102. package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.js +0 -1
  103. package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.js.map +1 -1
  104. package/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.pure.js +7 -0
  105. package/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.pure.js.map +1 -1
  106. package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.d.ts +0 -1
  107. package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.js +0 -1
  108. package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.js.map +1 -1
  109. package/PostProcesses/postProcess.pure.js +5 -0
  110. package/PostProcesses/postProcess.pure.js.map +1 -1
  111. package/PostProcesses/vrMultiviewToSingleviewPostProcess.d.ts +0 -1
  112. package/PostProcesses/vrMultiviewToSingleviewPostProcess.js +0 -1
  113. package/PostProcesses/vrMultiviewToSingleviewPostProcess.js.map +1 -1
  114. package/PostProcesses/vrMultiviewToSingleviewPostProcess.pure.js +2 -0
  115. package/PostProcesses/vrMultiviewToSingleviewPostProcess.pure.js.map +1 -1
  116. package/Rendering/IBLShadows/iblShadowsRenderPipeline.d.ts +0 -2
  117. package/Rendering/IBLShadows/iblShadowsRenderPipeline.js +0 -2
  118. package/Rendering/IBLShadows/iblShadowsRenderPipeline.js.map +1 -1
  119. package/Rendering/IBLShadows/iblShadowsRenderPipeline.pure.js +5 -0
  120. package/Rendering/IBLShadows/iblShadowsRenderPipeline.pure.js.map +1 -1
  121. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.d.ts +0 -1
  122. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js +0 -1
  123. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js.map +1 -1
  124. package/Rendering/prePassRenderer.d.ts +0 -2
  125. package/Rendering/prePassRenderer.js +0 -2
  126. package/Rendering/prePassRenderer.js.map +1 -1
  127. package/Rendering/prePassRenderer.pure.js +2 -0
  128. package/Rendering/prePassRenderer.pure.js.map +1 -1
  129. package/Rendering/thinDepthPeelingRenderer.d.ts +0 -1
  130. package/Rendering/thinDepthPeelingRenderer.js +0 -1
  131. package/Rendering/thinDepthPeelingRenderer.js.map +1 -1
  132. package/Shaders/ShadersInclude/openpbrEnvironmentLighting.js +35 -5
  133. package/Shaders/ShadersInclude/openpbrEnvironmentLighting.js.map +1 -1
  134. package/ShadersWGSL/ShadersInclude/helperFunctions.js +2 -2
  135. package/ShadersWGSL/ShadersInclude/helperFunctions.js.map +1 -1
  136. package/ShadersWGSL/ShadersInclude/openpbrEnvironmentLighting.js +39 -7
  137. package/ShadersWGSL/ShadersInclude/openpbrEnvironmentLighting.js.map +1 -1
  138. package/index.d.ts +1 -0
  139. package/index.js +1 -0
  140. package/index.js.map +1 -1
  141. package/package.json +3 -11
@@ -3,6 +3,7 @@ import { serialize } from "../../Misc/decorators.js";
3
3
  import { CameraInputTypes } from "../../Cameras/cameraInputsManager.js";
4
4
  import { KeyboardEventTypes } from "../../Events/keyboardEvents.js";
5
5
  import { Tools } from "../../Misc/tools.pure.js";
6
+ import { Vector2 } from "../../Maths/math.vector.pure.js";
6
7
  /**
7
8
  * Manage the keyboard inputs to control the movement of an arc rotate camera.
8
9
  * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs
@@ -65,6 +66,9 @@ export class ArcRotateCameraKeyboardMoveInput {
65
66
  this._keyboardModifiers = { ctrl: false, alt: false };
66
67
  /** Cached conditions object to avoid per-frame allocations in checkInputs */
67
68
  this._keyboardConditions = { modifiers: this._keyboardModifiers };
69
+ /** Reused accumulators for the per-frame keyboard rotate/pan directions, to avoid per-frame allocations */
70
+ this._rotateDirection = new Vector2();
71
+ this._panDirection = new Vector2();
68
72
  }
69
73
  /**
70
74
  * Defines whether alt+arrows/wasd triggers zoom instead of rotation/pan.
@@ -185,6 +189,14 @@ export class ArcRotateCameraKeyboardMoveInput {
185
189
  const input = camera.movement.input;
186
190
  this._keyboardModifiers.ctrl = this._ctrlPressed;
187
191
  this._keyboardModifiers.alt = this._altPressed;
192
+ // Rotate and pan directions are accumulated across keys and applied once below (normalized), so
193
+ // holding two directions at once (e.g. up + left) moves along a normalized diagonal at the same
194
+ // speed as a single direction, instead of the ~1.41x boost (sqrt(2)) that results from applying
195
+ // each key independently. Zoom is one-dimensional and is applied per key.
196
+ const rotateDirection = this._rotateDirection.set(0, 0);
197
+ const panDirection = this._panDirection.set(0, 0);
198
+ let rotateSensitivity = 0;
199
+ let panSensitivity = 0;
188
200
  for (let index = 0; index < this._keys.length; index++) {
189
201
  const keyCode = this._keys[index];
190
202
  this._keyboardConditions.key = keyCode;
@@ -198,18 +210,21 @@ export class ArcRotateCameraKeyboardMoveInput {
198
210
  // legacy sensibility/angularSpeed properties over time). When `sensitivity` is
199
211
  // undefined, fall back to the legacy properties for backward compatibility.
200
212
  if (resolved.interaction === "pan") {
201
- const panSens = resolved.sensitivity ?? 1 / this.panningSensibility;
213
+ // Accumulate a unit direction per pan key; the combined vector is normalized after the loop.
214
+ // Aggregate sensitivity with max so the pan speed is independent of key insertion order
215
+ // when keys resolve to different per-key sensitivities.
216
+ panSensitivity = Math.max(panSensitivity, resolved.sensitivity ?? 1 / this.panningSensibility);
202
217
  if (this.keysLeft.indexOf(keyCode) !== -1) {
203
- input.handlers.pan(-panSens, 0);
218
+ panDirection.x -= 1;
204
219
  }
205
220
  else if (this.keysRight.indexOf(keyCode) !== -1) {
206
- input.handlers.pan(panSens, 0);
221
+ panDirection.x += 1;
207
222
  }
208
223
  else if (this.keysUp.indexOf(keyCode) !== -1) {
209
- input.handlers.pan(0, panSens);
224
+ panDirection.y += 1;
210
225
  }
211
226
  else if (this.keysDown.indexOf(keyCode) !== -1) {
212
- input.handlers.pan(0, -panSens);
227
+ panDirection.y -= 1;
213
228
  }
214
229
  }
215
230
  else if (resolved.interaction === "zoom") {
@@ -222,18 +237,21 @@ export class ArcRotateCameraKeyboardMoveInput {
222
237
  }
223
238
  }
224
239
  else if (resolved.interaction === "rotate") {
225
- const rotateSens = resolved.sensitivity ?? this.angularSpeed;
240
+ // Accumulate a unit direction per rotate key; the combined vector is normalized after the loop.
241
+ // Aggregate sensitivity with max so the rotate speed is independent of key insertion order
242
+ // when keys resolve to different per-key sensitivities.
243
+ rotateSensitivity = Math.max(rotateSensitivity, resolved.sensitivity ?? this.angularSpeed);
226
244
  if (this.keysLeft.indexOf(keyCode) !== -1) {
227
- input.handlers.rotate(-rotateSens, 0);
245
+ rotateDirection.x -= 1;
228
246
  }
229
247
  else if (this.keysRight.indexOf(keyCode) !== -1) {
230
- input.handlers.rotate(rotateSens, 0);
248
+ rotateDirection.x += 1;
231
249
  }
232
250
  else if (this.keysUp.indexOf(keyCode) !== -1) {
233
- input.handlers.rotate(0, -rotateSens);
251
+ rotateDirection.y -= 1;
234
252
  }
235
253
  else if (this.keysDown.indexOf(keyCode) !== -1) {
236
- input.handlers.rotate(0, rotateSens);
254
+ rotateDirection.y += 1;
237
255
  }
238
256
  }
239
257
  }
@@ -244,6 +262,15 @@ export class ArcRotateCameraKeyboardMoveInput {
244
262
  }
245
263
  }
246
264
  }
265
+ // Apply the accumulated rotate/pan once, normalized so a diagonal isn't faster than an axis-aligned move.
266
+ if (rotateDirection.x !== 0 || rotateDirection.y !== 0) {
267
+ rotateDirection.normalize().scaleInPlace(rotateSensitivity);
268
+ input.handlers.rotate(rotateDirection.x, rotateDirection.y);
269
+ }
270
+ if (panDirection.x !== 0 || panDirection.y !== 0) {
271
+ panDirection.normalize().scaleInPlace(panSensitivity);
272
+ input.handlers.pan(panDirection.x, panDirection.y);
273
+ }
247
274
  }
248
275
  }
249
276
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"arcRotateCameraKeyboardMoveInput.js","sourceRoot":"","sources":["../../../../../dev/core/src/Cameras/Inputs/arcRotateCameraKeyboardMoveInput.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 ArcRotateCamera } from \"../../Cameras/arcRotateCamera\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type KeyboardInfo, KeyboardEventTypes } from \"../../Events/keyboardEvents\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { type KeyboardConditions } from \"../inputMapper\";\r\n\r\n/**\r\n * Manage the keyboard inputs to control the movement of an arc rotate camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class ArcRotateCameraKeyboardMoveInput implements ICameraInput<ArcRotateCamera> {\r\n /**\r\n * Defines the camera the input is attached to.\r\n */\r\n public camera: ArcRotateCamera;\r\n\r\n /**\r\n * Defines the list of key codes associated with the up action (increase alpha)\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 (decrease alpha)\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 (increase beta)\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 (decrease beta)\r\n */\r\n @serialize()\r\n public keysRight = [39];\r\n\r\n /**\r\n * Defines the list of key codes associated with the reset action.\r\n * Those keys reset the camera to its last stored state (with the method camera.storeState())\r\n */\r\n @serialize()\r\n public keysReset = [220];\r\n\r\n /**\r\n * Defines the list of key codes associated with the zoom in action.\r\n * Only used when CameraMovement is active — these keys always trigger zoom regardless of modifiers.\r\n */\r\n @serialize()\r\n public keysZoomIn: number[] = [187, 107]; // 187 = +/= key, 107 = numpad +\r\n\r\n /**\r\n * Defines the list of key codes associated with the zoom out action.\r\n * Only used when CameraMovement is active — these keys always trigger zoom regardless of modifiers.\r\n */\r\n @serialize()\r\n public keysZoomOut: number[] = [189, 109]; // 189 = -/_ key, 109 = numpad -\r\n\r\n /**\r\n * Defines the panning sensibility of the inputs.\r\n * (How fast is the camera panning)\r\n */\r\n @serialize()\r\n public panningSensibility: number = 50.0;\r\n\r\n /**\r\n * Defines the zooming sensibility of the inputs.\r\n * (How fast is the camera zooming)\r\n */\r\n @serialize()\r\n public zoomingSensibility: number = 25.0;\r\n\r\n /**\r\n * Rotation speed of the camera\r\n */\r\n @serialize()\r\n public angularSpeed = 0.01;\r\n\r\n private _useAltToZoom: boolean = true;\r\n\r\n /**\r\n * Defines whether alt+arrows/wasd triggers zoom instead of rotation/pan.\r\n * When disabled, alt+keyboard events are ignored by the zoom inputMap entry.\r\n * Setting this updates the corresponding inputMap entry on the camera's movement system.\r\n * If set before the camera is attached, the value is cached and applied during `attachControl`.\r\n */\r\n @serialize()\r\n public get useAltToZoom(): boolean {\r\n return this._useAltToZoom;\r\n }\r\n\r\n public set useAltToZoom(value: boolean) {\r\n this._useAltToZoom = value;\r\n this._applyUseAltToZoomToInputMap();\r\n }\r\n\r\n /**\r\n * Applies the cached `_useAltToZoom` value to the camera's inputMap.\r\n * Safe to call before the camera is attached: it is a no-op until `this.camera.movement` is available.\r\n * Idempotent — calling it when the inputMap already matches the cached value is a no-op.\r\n */\r\n private _applyUseAltToZoomToInputMap(): void {\r\n if (!this.camera?.movement) {\r\n return;\r\n }\r\n const input = this.camera.movement.input;\r\n const entry = input.getEntry(\"keyboard\", \"zoom\", { modifiers: { alt: true } });\r\n if (!this._useAltToZoom && entry) {\r\n input.inputMap.splice(input.inputMap.indexOf(entry), 1);\r\n } else if (this._useAltToZoom && !entry) {\r\n input.addEntry({ source: \"keyboard\", modifiers: { alt: true }, interaction: \"zoom\" });\r\n }\r\n }\r\n\r\n private _keys = new Array<number>();\r\n private _ctrlPressed: boolean;\r\n private _altPressed: 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 * Modifier state stored separately from `_keyboardConditions` so it can be typed as a\r\n * concrete (non-optional) object. This avoids non-null assertions when updating modifier\r\n * fields each frame, and the conditions object holds the same reference so\r\n * resolveInteraction sees the live state.\r\n */\r\n private _keyboardModifiers: { ctrl: boolean; alt: boolean } = { ctrl: false, alt: false };\r\n\r\n /** Cached conditions object to avoid per-frame allocations in checkInputs */\r\n private _keyboardConditions: KeyboardConditions = { modifiers: this._keyboardModifiers };\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._applyUseAltToZoomToInputMap();\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 this._altPressed = evt.altKey;\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.keysReset.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.keysReset.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 if (this._onKeyboardObserver) {\r\n this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);\r\n }\r\n if (this._onCanvasBlurObserver) {\r\n this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);\r\n }\r\n this._onKeyboardObserver = null;\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 const input = camera.movement.input;\r\n\r\n this._keyboardModifiers.ctrl = this._ctrlPressed;\r\n this._keyboardModifiers.alt = this._altPressed;\r\n\r\n for (let index = 0; index < this._keys.length; index++) {\r\n const keyCode = this._keys[index];\r\n\r\n this._keyboardConditions.key = keyCode;\r\n\r\n // Skip resolveInteraction for the reset key — it has no inputMap entry of its own\r\n // and would otherwise spuriously match the catch-all keyboard→rotate entry.\r\n if (this.keysReset.indexOf(keyCode) === -1) {\r\n const resolved = input.resolveInteraction(\"keyboard\", this._keyboardConditions);\r\n\r\n if (resolved) {\r\n // Per-frame impulse magnitude. The inputMap entry's `sensitivity` takes precedence\r\n // when set so consumers can tune feel declaratively (and so we can phase out the\r\n // legacy sensibility/angularSpeed properties over time). When `sensitivity` is\r\n // undefined, fall back to the legacy properties for backward compatibility.\r\n if (resolved.interaction === \"pan\") {\r\n const panSens = resolved.sensitivity ?? 1 / this.panningSensibility;\r\n if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n input.handlers.pan(-panSens, 0);\r\n } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n input.handlers.pan(panSens, 0);\r\n } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n input.handlers.pan(0, panSens);\r\n } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n input.handlers.pan(0, -panSens);\r\n }\r\n } else if (resolved.interaction === \"zoom\") {\r\n const zoomSens = resolved.sensitivity ?? 1 / this.zoomingSensibility;\r\n if (this.keysUp.indexOf(keyCode) !== -1 || this.keysZoomIn.indexOf(keyCode) !== -1) {\r\n input.handlers.zoom(zoomSens);\r\n } else if (this.keysDown.indexOf(keyCode) !== -1 || this.keysZoomOut.indexOf(keyCode) !== -1) {\r\n input.handlers.zoom(-zoomSens);\r\n }\r\n } else if (resolved.interaction === \"rotate\") {\r\n const rotateSens = resolved.sensitivity ?? this.angularSpeed;\r\n if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n input.handlers.rotate(-rotateSens, 0);\r\n } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n input.handlers.rotate(rotateSens, 0);\r\n } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n input.handlers.rotate(0, -rotateSens);\r\n } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n input.handlers.rotate(0, rotateSens);\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (this.keysReset.indexOf(keyCode) !== -1) {\r\n if (camera.useInputToRestoreState) {\r\n camera.restoreState();\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 \"ArcRotateCameraKeyboardMoveInput\";\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)[\"ArcRotateCameraKeyboardMoveInput\"] = ArcRotateCameraKeyboardMoveInput;\r\n"]}
1
+ {"version":3,"file":"arcRotateCameraKeyboardMoveInput.js","sourceRoot":"","sources":["../../../../../dev/core/src/Cameras/Inputs/arcRotateCameraKeyboardMoveInput.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 ArcRotateCamera } from \"../../Cameras/arcRotateCamera\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type KeyboardInfo, KeyboardEventTypes } from \"../../Events/keyboardEvents\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { type KeyboardConditions } from \"../inputMapper\";\r\nimport { Vector2 } from \"../../Maths/math.vector.pure\";\r\n\r\n/**\r\n * Manage the keyboard inputs to control the movement of an arc rotate camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class ArcRotateCameraKeyboardMoveInput implements ICameraInput<ArcRotateCamera> {\r\n /**\r\n * Defines the camera the input is attached to.\r\n */\r\n public camera: ArcRotateCamera;\r\n\r\n /**\r\n * Defines the list of key codes associated with the up action (increase alpha)\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 (decrease alpha)\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 (increase beta)\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 (decrease beta)\r\n */\r\n @serialize()\r\n public keysRight = [39];\r\n\r\n /**\r\n * Defines the list of key codes associated with the reset action.\r\n * Those keys reset the camera to its last stored state (with the method camera.storeState())\r\n */\r\n @serialize()\r\n public keysReset = [220];\r\n\r\n /**\r\n * Defines the list of key codes associated with the zoom in action.\r\n * Only used when CameraMovement is active — these keys always trigger zoom regardless of modifiers.\r\n */\r\n @serialize()\r\n public keysZoomIn: number[] = [187, 107]; // 187 = +/= key, 107 = numpad +\r\n\r\n /**\r\n * Defines the list of key codes associated with the zoom out action.\r\n * Only used when CameraMovement is active — these keys always trigger zoom regardless of modifiers.\r\n */\r\n @serialize()\r\n public keysZoomOut: number[] = [189, 109]; // 189 = -/_ key, 109 = numpad -\r\n\r\n /**\r\n * Defines the panning sensibility of the inputs.\r\n * (How fast is the camera panning)\r\n */\r\n @serialize()\r\n public panningSensibility: number = 50.0;\r\n\r\n /**\r\n * Defines the zooming sensibility of the inputs.\r\n * (How fast is the camera zooming)\r\n */\r\n @serialize()\r\n public zoomingSensibility: number = 25.0;\r\n\r\n /**\r\n * Rotation speed of the camera\r\n */\r\n @serialize()\r\n public angularSpeed = 0.01;\r\n\r\n private _useAltToZoom: boolean = true;\r\n\r\n /**\r\n * Defines whether alt+arrows/wasd triggers zoom instead of rotation/pan.\r\n * When disabled, alt+keyboard events are ignored by the zoom inputMap entry.\r\n * Setting this updates the corresponding inputMap entry on the camera's movement system.\r\n * If set before the camera is attached, the value is cached and applied during `attachControl`.\r\n */\r\n @serialize()\r\n public get useAltToZoom(): boolean {\r\n return this._useAltToZoom;\r\n }\r\n\r\n public set useAltToZoom(value: boolean) {\r\n this._useAltToZoom = value;\r\n this._applyUseAltToZoomToInputMap();\r\n }\r\n\r\n /**\r\n * Applies the cached `_useAltToZoom` value to the camera's inputMap.\r\n * Safe to call before the camera is attached: it is a no-op until `this.camera.movement` is available.\r\n * Idempotent — calling it when the inputMap already matches the cached value is a no-op.\r\n */\r\n private _applyUseAltToZoomToInputMap(): void {\r\n if (!this.camera?.movement) {\r\n return;\r\n }\r\n const input = this.camera.movement.input;\r\n const entry = input.getEntry(\"keyboard\", \"zoom\", { modifiers: { alt: true } });\r\n if (!this._useAltToZoom && entry) {\r\n input.inputMap.splice(input.inputMap.indexOf(entry), 1);\r\n } else if (this._useAltToZoom && !entry) {\r\n input.addEntry({ source: \"keyboard\", modifiers: { alt: true }, interaction: \"zoom\" });\r\n }\r\n }\r\n\r\n private _keys = new Array<number>();\r\n private _ctrlPressed: boolean;\r\n private _altPressed: 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 * Modifier state stored separately from `_keyboardConditions` so it can be typed as a\r\n * concrete (non-optional) object. This avoids non-null assertions when updating modifier\r\n * fields each frame, and the conditions object holds the same reference so\r\n * resolveInteraction sees the live state.\r\n */\r\n private _keyboardModifiers: { ctrl: boolean; alt: boolean } = { ctrl: false, alt: false };\r\n\r\n /** Cached conditions object to avoid per-frame allocations in checkInputs */\r\n private _keyboardConditions: KeyboardConditions = { modifiers: this._keyboardModifiers };\r\n\r\n /** Reused accumulators for the per-frame keyboard rotate/pan directions, to avoid per-frame allocations */\r\n private _rotateDirection = new Vector2();\r\n private _panDirection = new Vector2();\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._applyUseAltToZoomToInputMap();\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 this._altPressed = evt.altKey;\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.keysReset.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.keysReset.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 if (this._onKeyboardObserver) {\r\n this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);\r\n }\r\n if (this._onCanvasBlurObserver) {\r\n this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);\r\n }\r\n this._onKeyboardObserver = null;\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 const input = camera.movement.input;\r\n\r\n this._keyboardModifiers.ctrl = this._ctrlPressed;\r\n this._keyboardModifiers.alt = this._altPressed;\r\n\r\n // Rotate and pan directions are accumulated across keys and applied once below (normalized), so\r\n // holding two directions at once (e.g. up + left) moves along a normalized diagonal at the same\r\n // speed as a single direction, instead of the ~1.41x boost (sqrt(2)) that results from applying\r\n // each key independently. Zoom is one-dimensional and is applied per key.\r\n const rotateDirection = this._rotateDirection.set(0, 0);\r\n const panDirection = this._panDirection.set(0, 0);\r\n let rotateSensitivity = 0;\r\n let panSensitivity = 0;\r\n\r\n for (let index = 0; index < this._keys.length; index++) {\r\n const keyCode = this._keys[index];\r\n\r\n this._keyboardConditions.key = keyCode;\r\n\r\n // Skip resolveInteraction for the reset key — it has no inputMap entry of its own\r\n // and would otherwise spuriously match the catch-all keyboard→rotate entry.\r\n if (this.keysReset.indexOf(keyCode) === -1) {\r\n const resolved = input.resolveInteraction(\"keyboard\", this._keyboardConditions);\r\n\r\n if (resolved) {\r\n // Per-frame impulse magnitude. The inputMap entry's `sensitivity` takes precedence\r\n // when set so consumers can tune feel declaratively (and so we can phase out the\r\n // legacy sensibility/angularSpeed properties over time). When `sensitivity` is\r\n // undefined, fall back to the legacy properties for backward compatibility.\r\n if (resolved.interaction === \"pan\") {\r\n // Accumulate a unit direction per pan key; the combined vector is normalized after the loop.\r\n // Aggregate sensitivity with max so the pan speed is independent of key insertion order\r\n // when keys resolve to different per-key sensitivities.\r\n panSensitivity = Math.max(panSensitivity, resolved.sensitivity ?? 1 / this.panningSensibility);\r\n if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n panDirection.x -= 1;\r\n } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n panDirection.x += 1;\r\n } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n panDirection.y += 1;\r\n } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n panDirection.y -= 1;\r\n }\r\n } else if (resolved.interaction === \"zoom\") {\r\n const zoomSens = resolved.sensitivity ?? 1 / this.zoomingSensibility;\r\n if (this.keysUp.indexOf(keyCode) !== -1 || this.keysZoomIn.indexOf(keyCode) !== -1) {\r\n input.handlers.zoom(zoomSens);\r\n } else if (this.keysDown.indexOf(keyCode) !== -1 || this.keysZoomOut.indexOf(keyCode) !== -1) {\r\n input.handlers.zoom(-zoomSens);\r\n }\r\n } else if (resolved.interaction === \"rotate\") {\r\n // Accumulate a unit direction per rotate key; the combined vector is normalized after the loop.\r\n // Aggregate sensitivity with max so the rotate speed is independent of key insertion order\r\n // when keys resolve to different per-key sensitivities.\r\n rotateSensitivity = Math.max(rotateSensitivity, resolved.sensitivity ?? this.angularSpeed);\r\n if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n rotateDirection.x -= 1;\r\n } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n rotateDirection.x += 1;\r\n } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n rotateDirection.y -= 1;\r\n } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n rotateDirection.y += 1;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (this.keysReset.indexOf(keyCode) !== -1) {\r\n if (camera.useInputToRestoreState) {\r\n camera.restoreState();\r\n }\r\n }\r\n }\r\n\r\n // Apply the accumulated rotate/pan once, normalized so a diagonal isn't faster than an axis-aligned move.\r\n if (rotateDirection.x !== 0 || rotateDirection.y !== 0) {\r\n rotateDirection.normalize().scaleInPlace(rotateSensitivity);\r\n input.handlers.rotate(rotateDirection.x, rotateDirection.y);\r\n }\r\n if (panDirection.x !== 0 || panDirection.y !== 0) {\r\n panDirection.normalize().scaleInPlace(panSensitivity);\r\n input.handlers.pan(panDirection.x, panDirection.y);\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 \"ArcRotateCameraKeyboardMoveInput\";\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)[\"ArcRotateCameraKeyboardMoveInput\"] = ArcRotateCameraKeyboardMoveInput;\r\n"]}
@@ -137,33 +137,43 @@ export class FlyCameraKeyboardInput {
137
137
  return;
138
138
  }
139
139
  const translateGain = translateEntry.sensitivity ?? 1;
140
+ // Movement keys are accumulated into a single local direction and applied once below, so that
141
+ // holding two directions at once (e.g. forward + left) moves along a normalized diagonal at the
142
+ // same speed as a single direction, instead of the ~1.41x boost (sqrt(2)) that results from
143
+ // applying each movement key independently.
144
+ const localDirection = camera._localDirection.copyFromFloats(0, 0, 0);
140
145
  // Keyboard
141
146
  for (let index = 0; index < this._keys.length; index++) {
142
147
  const keyCode = this._keys[index];
143
- const speed = camera._computeLocalCameraSpeed() * translateGain;
144
148
  if (this.keysForward.indexOf(keyCode) !== -1) {
145
- camera._localDirection.copyFromFloats(0, 0, speed);
149
+ localDirection.z += 1;
146
150
  }
147
151
  else if (this.keysBackward.indexOf(keyCode) !== -1) {
148
- camera._localDirection.copyFromFloats(0, 0, -speed);
152
+ localDirection.z -= 1;
149
153
  }
150
154
  else if (this.keysUp.indexOf(keyCode) !== -1) {
151
- camera._localDirection.copyFromFloats(0, speed, 0);
155
+ localDirection.y += 1;
152
156
  }
153
157
  else if (this.keysDown.indexOf(keyCode) !== -1) {
154
- camera._localDirection.copyFromFloats(0, -speed, 0);
158
+ localDirection.y -= 1;
155
159
  }
156
160
  else if (this.keysRight.indexOf(keyCode) !== -1) {
157
- camera._localDirection.copyFromFloats(speed, 0, 0);
161
+ localDirection.x += 1;
158
162
  }
159
163
  else if (this.keysLeft.indexOf(keyCode) !== -1) {
160
- camera._localDirection.copyFromFloats(-speed, 0, 0);
164
+ localDirection.x -= 1;
161
165
  }
166
+ }
167
+ // Apply a single, normalized movement once all keys for this frame have been accumulated.
168
+ if (localDirection.x !== 0 || localDirection.y !== 0 || localDirection.z !== 0) {
169
+ const speed = camera._computeLocalCameraSpeed() * translateGain;
170
+ // Normalize so a diagonal isn't faster than an axis-aligned move, then scale to the per-frame speed.
171
+ localDirection.normalize().scaleInPlace(speed);
162
172
  if (camera.getScene().useRightHandedSystem) {
163
- camera._localDirection.z *= -1;
173
+ localDirection.z *= -1;
164
174
  }
165
175
  camera.getViewMatrix().invertToRef(camera._cameraTransformMatrix);
166
- Vector3.TransformNormalToRef(camera._localDirection, camera._cameraTransformMatrix, camera._transformedDirection);
176
+ Vector3.TransformNormalToRef(localDirection, camera._cameraTransformMatrix, camera._transformedDirection);
167
177
  camera.cameraDirection.addInPlace(camera._transformedDirection);
168
178
  }
169
179
  }
@@ -1 +1 @@
1
- {"version":3,"file":"flyCameraKeyboardInput.js","sourceRoot":"","sources":["../../../../../dev/core/src/Cameras/Inputs/flyCameraKeyboardInput.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,OAAO,EAAqB,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAExF,OAAO,EAAqB,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEpF,OAAO,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAG9C;;;GAGG;AACH,MAAM,OAAO,sBAAsB;IAAnC;QAMI;;WAEG;QAEI,gBAAW,GAAG,CAAC,EAAE,CAAC,CAAC;QAE1B;;WAEG;QAEI,iBAAY,GAAG,CAAC,EAAE,CAAC,CAAC;QAE3B;;WAEG;QAEI,WAAM,GAAG,CAAC,EAAE,CAAC,CAAC;QAErB;;WAEG;QAEI,aAAQ,GAAG,CAAC,EAAE,CAAC,CAAC;QAEvB;;WAEG;QAEI,cAAS,GAAG,CAAC,EAAE,CAAC,CAAC;QAExB;;WAEG;QAEI,aAAQ,GAAG,CAAC,EAAE,CAAC,CAAC;QAEf,UAAK,GAAG,IAAI,KAAK,EAAU,CAAC;IAuJxC,CAAC;IAjJG;;;OAGG;IACI,aAAa,CAAC,gBAA0B;QAC3C,gBAAgB,GAAG,KAAK,CAAC,gCAAgC,CAAC,SAAS,CAAC,CAAC;QACrE,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;YAEvB,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB,CAAC,OAAO,EAAE,CAAC;gBAC3C,IACI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBAC5C,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBAC7C,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBACvC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBACzC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBACzC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAC5C,CAAC;oBACC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBAE9C,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;wBACf,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBACjC,CAAC;oBACD,IAAI,CAAC,gBAAgB,EAAE,CAAC;wBACpB,GAAG,CAAC,cAAc,EAAE,CAAC;oBACzB,CAAC;gBACL,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,IACI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBAC5C,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBAC7C,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBACvC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBACzC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBACzC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAC5C,CAAC;oBACC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBAE9C,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;wBACb,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;oBAChC,CAAC;oBACD,IAAI,CAAC,gBAAgB,EAAE,CAAC;wBACpB,GAAG,CAAC,cAAc,EAAE,CAAC;oBACzB,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACI,aAAa;QAChB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3B,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YACtE,CAAC;YAED,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC7B,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;YAC3E,CAAC;YACD,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;YAChC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QACtC,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACI,YAAY;QACf,OAAO,wBAAwB,CAAC;IACpC,CAAC;IAED;;OAEG;IACI,YAAY;QACf,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACI,aAAa;QAChB,OAAO,UAAU,CAAC;IACtB,CAAC;IAED;;;OAGG;IACI,WAAW;QACd,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YAC3B,qFAAqF;YACrF,kFAAkF;YAClF,iEAAiE;YACjE,MAAM,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;YAC/E,IAAI,CAAC,cAAc,EAAE,CAAC;gBAClB,OAAO;YACX,CAAC;YACD,MAAM,aAAa,GAAG,cAAc,CAAC,WAAW,IAAI,CAAC,CAAC;YACtD,WAAW;YACX,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,MAAM,KAAK,GAAG,MAAM,CAAC,wBAAwB,EAAE,GAAG,aAAa,CAAC;gBAEhE,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;oBAC3C,MAAM,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBACvD,CAAC;qBAAM,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;oBACnD,MAAM,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;gBACxD,CAAC;qBAAM,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;oBAC7C,MAAM,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;gBACvD,CAAC;qBAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;oBAC/C,MAAM,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBACxD,CAAC;qBAAM,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;oBAChD,MAAM,CAAC,eAAe,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBACvD,CAAC;qBAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;oBAC/C,MAAM,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBACxD,CAAC;gBAED,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC,oBAAoB,EAAE,CAAC;oBACzC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;gBACnC,CAAC;gBAED,MAAM,CAAC,aAAa,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;gBAClE,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,sBAAsB,EAAE,MAAM,CAAC,qBAAqB,CAAC,CAAC;gBAClH,MAAM,CAAC,eAAe,CAAC,UAAU,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;YACpE,CAAC;QACL,CAAC;IACL,CAAC;CACJ;AAvLU;IADN,SAAS,EAAE;2DACc;AAMnB;IADN,SAAS,EAAE;4DACe;AAMpB;IADN,SAAS,EAAE;sDACS;AAMd;IADN,SAAS,EAAE;wDACW;AAMhB;IADN,SAAS,EAAE;yDACY;AAMjB;IADN,SAAS,EAAE;wDACW;AA2JrB,gBAAiB,CAAC,wBAAwB,CAAC,GAAG,sBAAsB,CAAC","sourcesContent":["import { type Nullable } from \"../../types\";\r\nimport { serialize } from \"../../Misc/decorators\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type FlyCamera } from \"../../Cameras/flyCamera\";\r\nimport { type KeyboardInfo, KeyboardEventTypes } from \"../../Events/keyboardEvents\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\n\r\n/**\r\n * Listen to keyboard events to control the camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FlyCameraKeyboardInput implements ICameraInput<FlyCamera> {\r\n /**\r\n * Defines the camera the input is attached to.\r\n */\r\n public camera: FlyCamera;\r\n\r\n /**\r\n * The list of keyboard keys used to control the forward move of the camera.\r\n */\r\n @serialize()\r\n public keysForward = [87];\r\n\r\n /**\r\n * The list of keyboard keys used to control the backward move of the camera.\r\n */\r\n @serialize()\r\n public keysBackward = [83];\r\n\r\n /**\r\n * The list of keyboard keys used to control the forward move of the camera.\r\n */\r\n @serialize()\r\n public keysUp = [69];\r\n\r\n /**\r\n * The list of keyboard keys used to control the backward move of the camera.\r\n */\r\n @serialize()\r\n public keysDown = [81];\r\n\r\n /**\r\n * The list of keyboard keys used to control the right strafe move of the camera.\r\n */\r\n @serialize()\r\n public keysRight = [68];\r\n\r\n /**\r\n * The list of keyboard keys used to control the left strafe move of the camera.\r\n */\r\n @serialize()\r\n public keysLeft = [65];\r\n\r\n private _keys = new Array<number>();\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 noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\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\r\n if (info.type === KeyboardEventTypes.KEYDOWN) {\r\n if (\r\n this.keysForward.indexOf(evt.keyCode) !== -1 ||\r\n this.keysBackward.indexOf(evt.keyCode) !== -1 ||\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 ) {\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 if (!noPreventDefault) {\r\n evt.preventDefault();\r\n }\r\n }\r\n } else {\r\n if (\r\n this.keysForward.indexOf(evt.keyCode) !== -1 ||\r\n this.keysBackward.indexOf(evt.keyCode) !== -1 ||\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 ) {\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 if (!noPreventDefault) {\r\n evt.preventDefault();\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 if (this._onKeyboardObserver) {\r\n this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);\r\n }\r\n\r\n if (this._onCanvasBlurObserver) {\r\n this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);\r\n }\r\n this._onKeyboardObserver = null;\r\n this._onCanvasBlurObserver = null;\r\n }\r\n this._keys.length = 0;\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 \"FlyCameraKeyboardInput\";\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _onLostFocus(): void {\r\n this._keys.length = 0;\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 * 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 // All fly-keyboard keys move the camera, so they are gated on the keyboard→translate\r\n // mapping. Removing that entry disables keyboard movement; an entry `sensitivity`\r\n // acts as a gain (default 1) over the legacy local-camera speed.\r\n const translateEntry = camera.movement.input.getEntry(\"keyboard\", \"translate\");\r\n if (!translateEntry) {\r\n return;\r\n }\r\n const translateGain = translateEntry.sensitivity ?? 1;\r\n // Keyboard\r\n for (let index = 0; index < this._keys.length; index++) {\r\n const keyCode = this._keys[index];\r\n const speed = camera._computeLocalCameraSpeed() * translateGain;\r\n\r\n if (this.keysForward.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(0, 0, speed);\r\n } else if (this.keysBackward.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(0, 0, -speed);\r\n } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(0, speed, 0);\r\n } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(0, -speed, 0);\r\n } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(speed, 0, 0);\r\n } else if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(-speed, 0, 0);\r\n }\r\n\r\n if (camera.getScene().useRightHandedSystem) {\r\n camera._localDirection.z *= -1;\r\n }\r\n\r\n camera.getViewMatrix().invertToRef(camera._cameraTransformMatrix);\r\n Vector3.TransformNormalToRef(camera._localDirection, camera._cameraTransformMatrix, camera._transformedDirection);\r\n camera.cameraDirection.addInPlace(camera._transformedDirection);\r\n }\r\n }\r\n }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"FlyCameraKeyboardInput\"] = FlyCameraKeyboardInput;\r\n"]}
1
+ {"version":3,"file":"flyCameraKeyboardInput.js","sourceRoot":"","sources":["../../../../../dev/core/src/Cameras/Inputs/flyCameraKeyboardInput.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 ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type FlyCamera } from \"../../Cameras/flyCamera\";\r\nimport { type KeyboardInfo, KeyboardEventTypes } from \"../../Events/keyboardEvents\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\n\r\n/**\r\n * Listen to keyboard events to control the camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FlyCameraKeyboardInput implements ICameraInput<FlyCamera> {\r\n /**\r\n * Defines the camera the input is attached to.\r\n */\r\n public camera: FlyCamera;\r\n\r\n /**\r\n * The list of keyboard keys used to control the forward move of the camera.\r\n */\r\n @serialize()\r\n public keysForward = [87];\r\n\r\n /**\r\n * The list of keyboard keys used to control the backward move of the camera.\r\n */\r\n @serialize()\r\n public keysBackward = [83];\r\n\r\n /**\r\n * The list of keyboard keys used to control the forward move of the camera.\r\n */\r\n @serialize()\r\n public keysUp = [69];\r\n\r\n /**\r\n * The list of keyboard keys used to control the backward move of the camera.\r\n */\r\n @serialize()\r\n public keysDown = [81];\r\n\r\n /**\r\n * The list of keyboard keys used to control the right strafe move of the camera.\r\n */\r\n @serialize()\r\n public keysRight = [68];\r\n\r\n /**\r\n * The list of keyboard keys used to control the left strafe move of the camera.\r\n */\r\n @serialize()\r\n public keysLeft = [65];\r\n\r\n private _keys = new Array<number>();\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 noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\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\r\n if (info.type === KeyboardEventTypes.KEYDOWN) {\r\n if (\r\n this.keysForward.indexOf(evt.keyCode) !== -1 ||\r\n this.keysBackward.indexOf(evt.keyCode) !== -1 ||\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 ) {\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 if (!noPreventDefault) {\r\n evt.preventDefault();\r\n }\r\n }\r\n } else {\r\n if (\r\n this.keysForward.indexOf(evt.keyCode) !== -1 ||\r\n this.keysBackward.indexOf(evt.keyCode) !== -1 ||\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 ) {\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 if (!noPreventDefault) {\r\n evt.preventDefault();\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 if (this._onKeyboardObserver) {\r\n this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);\r\n }\r\n\r\n if (this._onCanvasBlurObserver) {\r\n this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);\r\n }\r\n this._onKeyboardObserver = null;\r\n this._onCanvasBlurObserver = null;\r\n }\r\n this._keys.length = 0;\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 \"FlyCameraKeyboardInput\";\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _onLostFocus(): void {\r\n this._keys.length = 0;\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 * 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 // All fly-keyboard keys move the camera, so they are gated on the keyboard→translate\r\n // mapping. Removing that entry disables keyboard movement; an entry `sensitivity`\r\n // acts as a gain (default 1) over the legacy local-camera speed.\r\n const translateEntry = camera.movement.input.getEntry(\"keyboard\", \"translate\");\r\n if (!translateEntry) {\r\n return;\r\n }\r\n const translateGain = translateEntry.sensitivity ?? 1;\r\n\r\n // Movement keys are accumulated into a single local direction and applied once below, so that\r\n // holding two directions at once (e.g. forward + left) moves along a normalized diagonal at the\r\n // same speed as a single direction, instead of the ~1.41x boost (sqrt(2)) that results from\r\n // applying each movement key independently.\r\n const localDirection = camera._localDirection.copyFromFloats(0, 0, 0);\r\n\r\n // Keyboard\r\n for (let index = 0; index < this._keys.length; index++) {\r\n const keyCode = this._keys[index];\r\n\r\n if (this.keysForward.indexOf(keyCode) !== -1) {\r\n localDirection.z += 1;\r\n } else if (this.keysBackward.indexOf(keyCode) !== -1) {\r\n localDirection.z -= 1;\r\n } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n localDirection.y += 1;\r\n } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n localDirection.y -= 1;\r\n } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n localDirection.x += 1;\r\n } else if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n localDirection.x -= 1;\r\n }\r\n }\r\n\r\n // Apply a single, normalized movement once all keys for this frame have been accumulated.\r\n if (localDirection.x !== 0 || localDirection.y !== 0 || localDirection.z !== 0) {\r\n const speed = camera._computeLocalCameraSpeed() * translateGain;\r\n // Normalize so a diagonal isn't faster than an axis-aligned move, then scale to the per-frame speed.\r\n localDirection.normalize().scaleInPlace(speed);\r\n\r\n if (camera.getScene().useRightHandedSystem) {\r\n localDirection.z *= -1;\r\n }\r\n\r\n camera.getViewMatrix().invertToRef(camera._cameraTransformMatrix);\r\n Vector3.TransformNormalToRef(localDirection, camera._cameraTransformMatrix, camera._transformedDirection);\r\n camera.cameraDirection.addInPlace(camera._transformedDirection);\r\n }\r\n }\r\n }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"FlyCameraKeyboardInput\"] = FlyCameraKeyboardInput;\r\n"]}
@@ -146,62 +146,65 @@ export class FreeCameraKeyboardMoveInput {
146
146
  const translateEntry = input.getEntry("keyboard", "translate");
147
147
  const rotateEntry = input.getEntry("keyboard", "rotate");
148
148
  const rotateGain = rotateEntry?.sensitivity ?? 1;
149
+ // Movement keys are accumulated into a single local direction and applied once below, so that
150
+ // holding two directions at once (e.g. forward + left) moves along a normalized diagonal at the
151
+ // same speed as a single direction, instead of the ~1.41x boost (sqrt(2)) that results from
152
+ // applying each movement key independently. Rotation keys act on separate angular axes and are
153
+ // applied directly as before.
154
+ const localDirection = camera._localDirection.copyFromFloats(0, 0, 0);
149
155
  // Keyboard
150
156
  for (let index = 0; index < this._keys.length; index++) {
151
157
  const keyCode = this._keys[index];
152
- const speed = camera._computeLocalCameraSpeed() * (translateEntry?.sensitivity ?? 1);
153
158
  if (this.keysLeft.indexOf(keyCode) !== -1) {
154
- camera._localDirection.copyFromFloats(-speed, 0, 0);
159
+ localDirection.x -= 1;
155
160
  }
156
161
  else if (this.keysUp.indexOf(keyCode) !== -1) {
157
- camera._localDirection.copyFromFloats(0, 0, speed);
162
+ localDirection.z += 1;
158
163
  }
159
164
  else if (this.keysRight.indexOf(keyCode) !== -1) {
160
- camera._localDirection.copyFromFloats(speed, 0, 0);
165
+ localDirection.x += 1;
161
166
  }
162
167
  else if (this.keysDown.indexOf(keyCode) !== -1) {
163
- camera._localDirection.copyFromFloats(0, 0, -speed);
168
+ localDirection.z -= 1;
164
169
  }
165
170
  else if (this.keysUpward.indexOf(keyCode) !== -1) {
166
- camera._localDirection.copyFromFloats(0, speed, 0);
171
+ localDirection.y += 1;
167
172
  }
168
173
  else if (this.keysDownward.indexOf(keyCode) !== -1) {
169
- camera._localDirection.copyFromFloats(0, -speed, 0);
174
+ localDirection.y -= 1;
170
175
  }
171
176
  else if (this.keysRotateLeft.indexOf(keyCode) !== -1) {
172
- camera._localDirection.copyFromFloats(0, 0, 0);
173
177
  if (rotateEntry) {
174
178
  camera.cameraRotation.y -= this._getLocalRotation() * rotateGain;
175
179
  }
176
180
  }
177
181
  else if (this.keysRotateRight.indexOf(keyCode) !== -1) {
178
- camera._localDirection.copyFromFloats(0, 0, 0);
179
182
  if (rotateEntry) {
180
183
  camera.cameraRotation.y += this._getLocalRotation() * rotateGain;
181
184
  }
182
185
  }
183
186
  else if (this.keysRotateUp.indexOf(keyCode) !== -1) {
184
- camera._localDirection.copyFromFloats(0, 0, 0);
185
187
  if (rotateEntry) {
186
188
  camera.cameraRotation.x -= this._getLocalRotation() * rotateGain;
187
189
  }
188
190
  }
189
191
  else if (this.keysRotateDown.indexOf(keyCode) !== -1) {
190
- camera._localDirection.copyFromFloats(0, 0, 0);
191
192
  if (rotateEntry) {
192
193
  camera.cameraRotation.x += this._getLocalRotation() * rotateGain;
193
194
  }
194
195
  }
195
- // Suppress accumulated translation when the keyboard→translate mapping is removed.
196
- // Rotation keys already zeroed `_localDirection`, so this is a no-op for them.
197
- if (!translateEntry) {
198
- camera._localDirection.copyFromFloats(0, 0, 0);
199
- }
196
+ }
197
+ // Apply a single, normalized movement once all keys for this frame have been accumulated.
198
+ // Translation is suppressed when the keyboard→translate mapping is removed.
199
+ if (translateEntry && (localDirection.x !== 0 || localDirection.y !== 0 || localDirection.z !== 0)) {
200
+ const speed = camera._computeLocalCameraSpeed() * (translateEntry.sensitivity ?? 1);
201
+ // Normalize so a diagonal isn't faster than an axis-aligned move, then scale to the per-frame speed.
202
+ localDirection.normalize().scaleInPlace(speed);
200
203
  if (camera.getScene().useRightHandedSystem) {
201
- camera._localDirection.z *= -1;
204
+ localDirection.z *= -1;
202
205
  }
203
206
  camera.getViewMatrix().invertToRef(camera._cameraTransformMatrix);
204
- Vector3.TransformNormalToRef(camera._localDirection, camera._cameraTransformMatrix, camera._transformedDirection);
207
+ Vector3.TransformNormalToRef(localDirection, camera._cameraTransformMatrix, camera._transformedDirection);
205
208
  camera.cameraDirection.addInPlace(camera._transformedDirection);
206
209
  }
207
210
  }
@@ -1 +1 @@
1
- {"version":3,"file":"freeCameraKeyboardMoveInput.js","sourceRoot":"","sources":["../../../../../dev/core/src/Cameras/Inputs/freeCameraKeyboardMoveInput.ts"],"names":[],"mappings":"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","sourcesContent":["import { serialize } from \"../../Misc/decorators\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type FreeCamera } from \"../../Cameras/freeCamera\";\r\nimport { type KeyboardInfo, KeyboardEventTypes } from \"../../Events/keyboardEvents\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\n/**\r\n * Manage the keyboard inputs to control the movement of a free camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FreeCameraKeyboardMoveInput implements ICameraInput<FreeCamera> {\r\n /**\r\n * Defines the camera the input is attached to.\r\n */\r\n public camera: FreeCamera;\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the forward move of the camera.\r\n */\r\n @serialize()\r\n public keysUp = [38];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the upward move of the camera.\r\n */\r\n @serialize()\r\n public keysUpward = [33];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the backward move of the camera.\r\n */\r\n @serialize()\r\n public keysDown = [40];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the downward move of the camera.\r\n */\r\n @serialize()\r\n public keysDownward = [34];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.\r\n */\r\n @serialize()\r\n public keysLeft = [37];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the right strafe move of the camera.\r\n */\r\n @serialize()\r\n public keysRight = [39];\r\n\r\n /**\r\n * Defines the pointer angular sensibility along the X and Y axis or how fast is the camera rotating.\r\n */\r\n @serialize()\r\n public rotationSpeed = 0.5;\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the left rotation move of the camera.\r\n */\r\n @serialize()\r\n public keysRotateLeft: number[] = [];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the right rotation move of the camera.\r\n */\r\n @serialize()\r\n public keysRotateRight: number[] = [];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the up rotation move of the camera.\r\n */\r\n @serialize()\r\n public keysRotateUp: number[] = [];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the down rotation move of the camera.\r\n */\r\n @serialize()\r\n public keysRotateDown: number[] = [];\r\n\r\n private _keys = new Array<number>();\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 noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\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 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.keysUpward.indexOf(evt.keyCode) !== -1 ||\r\n this.keysDownward.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateLeft.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateRight.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateUp.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateDown.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 if (!noPreventDefault) {\r\n evt.preventDefault();\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.keysUpward.indexOf(evt.keyCode) !== -1 ||\r\n this.keysDownward.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateLeft.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateRight.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateUp.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateDown.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 if (!noPreventDefault) {\r\n evt.preventDefault();\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 if (this._onKeyboardObserver) {\r\n this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);\r\n }\r\n\r\n if (this._onCanvasBlurObserver) {\r\n this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);\r\n }\r\n this._onKeyboardObserver = null;\r\n this._onCanvasBlurObserver = null;\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 // Movement keys are gated on the keyboard→translate mapping and rotation keys on\r\n // keyboard→rotate. Removing the corresponding entry disables that family of keys.\r\n // An entry's optional `sensitivity` acts as a gain (default 1) over the legacy scaling.\r\n const input = camera.movement.input;\r\n const translateEntry = input.getEntry(\"keyboard\", \"translate\");\r\n const rotateEntry = input.getEntry(\"keyboard\", \"rotate\");\r\n const rotateGain = rotateEntry?.sensitivity ?? 1;\r\n // Keyboard\r\n for (let index = 0; index < this._keys.length; index++) {\r\n const keyCode = this._keys[index];\r\n const speed = camera._computeLocalCameraSpeed() * (translateEntry?.sensitivity ?? 1);\r\n\r\n if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(-speed, 0, 0);\r\n } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(0, 0, speed);\r\n } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(speed, 0, 0);\r\n } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(0, 0, -speed);\r\n } else if (this.keysUpward.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(0, speed, 0);\r\n } else if (this.keysDownward.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(0, -speed, 0);\r\n } else if (this.keysRotateLeft.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(0, 0, 0);\r\n if (rotateEntry) {\r\n camera.cameraRotation.y -= this._getLocalRotation() * rotateGain;\r\n }\r\n } else if (this.keysRotateRight.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(0, 0, 0);\r\n if (rotateEntry) {\r\n camera.cameraRotation.y += this._getLocalRotation() * rotateGain;\r\n }\r\n } else if (this.keysRotateUp.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(0, 0, 0);\r\n if (rotateEntry) {\r\n camera.cameraRotation.x -= this._getLocalRotation() * rotateGain;\r\n }\r\n } else if (this.keysRotateDown.indexOf(keyCode) !== -1) {\r\n camera._localDirection.copyFromFloats(0, 0, 0);\r\n if (rotateEntry) {\r\n camera.cameraRotation.x += this._getLocalRotation() * rotateGain;\r\n }\r\n }\r\n\r\n // Suppress accumulated translation when the keyboard→translate mapping is removed.\r\n // Rotation keys already zeroed `_localDirection`, so this is a no-op for them.\r\n if (!translateEntry) {\r\n camera._localDirection.copyFromFloats(0, 0, 0);\r\n }\r\n\r\n if (camera.getScene().useRightHandedSystem) {\r\n camera._localDirection.z *= -1;\r\n }\r\n\r\n camera.getViewMatrix().invertToRef(camera._cameraTransformMatrix);\r\n Vector3.TransformNormalToRef(camera._localDirection, camera._cameraTransformMatrix, camera._transformedDirection);\r\n camera.cameraDirection.addInPlace(camera._transformedDirection);\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 \"FreeCameraKeyboardMoveInput\";\r\n }\r\n\r\n /** @internal */\r\n public _onLostFocus(): void {\r\n this._keys.length = 0;\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 private _getLocalRotation(): number {\r\n const handednessMultiplier = this.camera._calculateHandednessMultiplier();\r\n const rotation = ((this.rotationSpeed * this._engine.getDeltaTime()) / 1000) * handednessMultiplier;\r\n\r\n return rotation;\r\n }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"FreeCameraKeyboardMoveInput\"] = FreeCameraKeyboardMoveInput;\r\n"]}
1
+ {"version":3,"file":"freeCameraKeyboardMoveInput.js","sourceRoot":"","sources":["../../../../../dev/core/src/Cameras/Inputs/freeCameraKeyboardMoveInput.ts"],"names":[],"mappings":"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","sourcesContent":["import { serialize } from \"../../Misc/decorators\";\r\nimport { type Observer } from \"../../Misc/observable\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type ICameraInput, CameraInputTypes } from \"../../Cameras/cameraInputsManager\";\r\nimport { type FreeCamera } from \"../../Cameras/freeCamera\";\r\nimport { type KeyboardInfo, KeyboardEventTypes } from \"../../Events/keyboardEvents\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { Vector3 } from \"../../Maths/math.vector.pure\";\r\nimport { Tools } from \"../../Misc/tools.pure\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\n/**\r\n * Manage the keyboard inputs to control the movement of a free camera.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs\r\n */\r\nexport class FreeCameraKeyboardMoveInput implements ICameraInput<FreeCamera> {\r\n /**\r\n * Defines the camera the input is attached to.\r\n */\r\n public camera: FreeCamera;\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the forward move of the camera.\r\n */\r\n @serialize()\r\n public keysUp = [38];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the upward move of the camera.\r\n */\r\n @serialize()\r\n public keysUpward = [33];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the backward move of the camera.\r\n */\r\n @serialize()\r\n public keysDown = [40];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the downward move of the camera.\r\n */\r\n @serialize()\r\n public keysDownward = [34];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.\r\n */\r\n @serialize()\r\n public keysLeft = [37];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the right strafe move of the camera.\r\n */\r\n @serialize()\r\n public keysRight = [39];\r\n\r\n /**\r\n * Defines the pointer angular sensibility along the X and Y axis or how fast is the camera rotating.\r\n */\r\n @serialize()\r\n public rotationSpeed = 0.5;\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the left rotation move of the camera.\r\n */\r\n @serialize()\r\n public keysRotateLeft: number[] = [];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the right rotation move of the camera.\r\n */\r\n @serialize()\r\n public keysRotateRight: number[] = [];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the up rotation move of the camera.\r\n */\r\n @serialize()\r\n public keysRotateUp: number[] = [];\r\n\r\n /**\r\n * Gets or Set the list of keyboard keys used to control the down rotation move of the camera.\r\n */\r\n @serialize()\r\n public keysRotateDown: number[] = [];\r\n\r\n private _keys = new Array<number>();\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 noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);\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 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.keysUpward.indexOf(evt.keyCode) !== -1 ||\r\n this.keysDownward.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateLeft.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateRight.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateUp.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateDown.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 if (!noPreventDefault) {\r\n evt.preventDefault();\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.keysUpward.indexOf(evt.keyCode) !== -1 ||\r\n this.keysDownward.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateLeft.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateRight.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateUp.indexOf(evt.keyCode) !== -1 ||\r\n this.keysRotateDown.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 if (!noPreventDefault) {\r\n evt.preventDefault();\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 if (this._onKeyboardObserver) {\r\n this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);\r\n }\r\n\r\n if (this._onCanvasBlurObserver) {\r\n this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);\r\n }\r\n this._onKeyboardObserver = null;\r\n this._onCanvasBlurObserver = null;\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 // Movement keys are gated on the keyboard→translate mapping and rotation keys on\r\n // keyboard→rotate. Removing the corresponding entry disables that family of keys.\r\n // An entry's optional `sensitivity` acts as a gain (default 1) over the legacy scaling.\r\n const input = camera.movement.input;\r\n const translateEntry = input.getEntry(\"keyboard\", \"translate\");\r\n const rotateEntry = input.getEntry(\"keyboard\", \"rotate\");\r\n const rotateGain = rotateEntry?.sensitivity ?? 1;\r\n\r\n // Movement keys are accumulated into a single local direction and applied once below, so that\r\n // holding two directions at once (e.g. forward + left) moves along a normalized diagonal at the\r\n // same speed as a single direction, instead of the ~1.41x boost (sqrt(2)) that results from\r\n // applying each movement key independently. Rotation keys act on separate angular axes and are\r\n // applied directly as before.\r\n const localDirection = camera._localDirection.copyFromFloats(0, 0, 0);\r\n\r\n // Keyboard\r\n for (let index = 0; index < this._keys.length; index++) {\r\n const keyCode = this._keys[index];\r\n\r\n if (this.keysLeft.indexOf(keyCode) !== -1) {\r\n localDirection.x -= 1;\r\n } else if (this.keysUp.indexOf(keyCode) !== -1) {\r\n localDirection.z += 1;\r\n } else if (this.keysRight.indexOf(keyCode) !== -1) {\r\n localDirection.x += 1;\r\n } else if (this.keysDown.indexOf(keyCode) !== -1) {\r\n localDirection.z -= 1;\r\n } else if (this.keysUpward.indexOf(keyCode) !== -1) {\r\n localDirection.y += 1;\r\n } else if (this.keysDownward.indexOf(keyCode) !== -1) {\r\n localDirection.y -= 1;\r\n } else if (this.keysRotateLeft.indexOf(keyCode) !== -1) {\r\n if (rotateEntry) {\r\n camera.cameraRotation.y -= this._getLocalRotation() * rotateGain;\r\n }\r\n } else if (this.keysRotateRight.indexOf(keyCode) !== -1) {\r\n if (rotateEntry) {\r\n camera.cameraRotation.y += this._getLocalRotation() * rotateGain;\r\n }\r\n } else if (this.keysRotateUp.indexOf(keyCode) !== -1) {\r\n if (rotateEntry) {\r\n camera.cameraRotation.x -= this._getLocalRotation() * rotateGain;\r\n }\r\n } else if (this.keysRotateDown.indexOf(keyCode) !== -1) {\r\n if (rotateEntry) {\r\n camera.cameraRotation.x += this._getLocalRotation() * rotateGain;\r\n }\r\n }\r\n }\r\n\r\n // Apply a single, normalized movement once all keys for this frame have been accumulated.\r\n // Translation is suppressed when the keyboard→translate mapping is removed.\r\n if (translateEntry && (localDirection.x !== 0 || localDirection.y !== 0 || localDirection.z !== 0)) {\r\n const speed = camera._computeLocalCameraSpeed() * (translateEntry.sensitivity ?? 1);\r\n // Normalize so a diagonal isn't faster than an axis-aligned move, then scale to the per-frame speed.\r\n localDirection.normalize().scaleInPlace(speed);\r\n\r\n if (camera.getScene().useRightHandedSystem) {\r\n localDirection.z *= -1;\r\n }\r\n\r\n camera.getViewMatrix().invertToRef(camera._cameraTransformMatrix);\r\n Vector3.TransformNormalToRef(localDirection, camera._cameraTransformMatrix, camera._transformedDirection);\r\n camera.cameraDirection.addInPlace(camera._transformedDirection);\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 \"FreeCameraKeyboardMoveInput\";\r\n }\r\n\r\n /** @internal */\r\n public _onLostFocus(): void {\r\n this._keys.length = 0;\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 private _getLocalRotation(): number {\r\n const handednessMultiplier = this.camera._calculateHandednessMultiplier();\r\n const rotation = ((this.rotationSpeed * this._engine.getDeltaTime()) / 1000) * handednessMultiplier;\r\n\r\n return rotation;\r\n }\r\n}\r\n\r\n(<any>CameraInputTypes)[\"FreeCameraKeyboardMoveInput\"] = FreeCameraKeyboardMoveInput;\r\n"]}
@@ -74,6 +74,8 @@ export declare class GeospatialCameraKeyboardInput implements ICameraInput<Geosp
74
74
  private _keyboardModifiers;
75
75
  /** Cached conditions object to avoid per-frame allocations in checkInputs */
76
76
  private _keyboardConditions;
77
+ /** Reused accumulator for the per-frame keyboard pan direction, to avoid per-frame allocations */
78
+ private _panDirection;
77
79
  /**
78
80
  * Attach the input controls to a specific dom element to get the input from.
79
81
  * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)