arcRotateCameraPointersInput.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. import { __decorate } from "../../tslib.es6.js";
  2. import { serialize } from "../../Misc/decorators.js";
  3. import { CameraInputTypes } from "../../Cameras/cameraInputsManager.js";
  4. import { BaseCameraPointersInput } from "../../Cameras/Inputs/BaseCameraPointersInput.js";
  5. /**
  6. * Manage the pointers inputs to control an arc rotate camera.
  7. * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs
  8. */
  9. export class ArcRotateCameraPointersInput extends BaseCameraPointersInput {
  10. constructor() {
  11. super(...arguments);
  12. /**
  13. * Defines the buttons associated with the input to handle camera move.
  14. */
  15. this.buttons = [0, 1, 2];
  16. /**
  17. * Defines the pointer angular sensibility along the X axis or how fast is
  18. * the camera rotating.
  19. */
  20. this.angularSensibilityX = 1000.0;
  21. /**
  22. * Defines the pointer angular sensibility along the Y axis or how fast is
  23. * the camera rotating.
  24. */
  25. this.angularSensibilityY = 1000.0;
  26. /**
  27. * Defines the pointer pinch precision or how fast is the camera zooming.
  28. */
  29. this.pinchPrecision = 12.0;
  30. /**
  31. * pinchDeltaPercentage will be used instead of pinchPrecision if different
  32. * from 0.
  33. * It defines the percentage of current camera.radius to use as delta when
  34. * pinch zoom is used.
  35. */
  36. this.pinchDeltaPercentage = 0;
  37. /**
  38. * When useNaturalPinchZoom is true, multi touch zoom will zoom in such
  39. * that any object in the plane at the camera's target point will scale
  40. * perfectly with finger motion.
  41. * Overrides pinchDeltaPercentage and pinchPrecision.
  42. */
  43. this.useNaturalPinchZoom = false;
  44. /**
  45. * Defines whether zoom (2 fingers pinch) is enabled through multitouch
  46. */
  47. this.pinchZoom = true;
  48. /**
  49. * Defines the pointer panning sensibility or how fast is the camera moving.
  50. */
  51. this.panningSensibility = 1000.0;
  52. /**
  53. * Defines whether panning (2 fingers swipe) is enabled through multitouch.
  54. */
  55. this.multiTouchPanning = true;
  56. /**
  57. * Defines whether panning is enabled for both pan (2 fingers swipe) and
  58. * zoom (pinch) through multitouch.
  59. */
  60. this.multiTouchPanAndZoom = true;
  61. /**
  62. * Revers pinch action direction.
  63. */
  64. this.pinchInwards = true;
  65. this._isPanClick = false;
  66. this._twoFingerActivityCount = 0;
  67. this._isPinching = false;
  68. }
  69. /**
  70. * Gets the class name of the current input.
  71. * @returns the class name
  72. */
  73. getClassName() {
  74. return "ArcRotateCameraPointersInput";
  75. }
  76. /**
  77. * Move camera from multi touch panning positions.
  78. * @param previousMultiTouchPanPosition
  79. * @param multiTouchPanPosition
  80. */
  81. _computeMultiTouchPanning(previousMultiTouchPanPosition, multiTouchPanPosition) {
  82. if (this.panningSensibility !== 0 && previousMultiTouchPanPosition && multiTouchPanPosition) {
  83. const moveDeltaX = multiTouchPanPosition.x - previousMultiTouchPanPosition.x;
  84. const moveDeltaY = multiTouchPanPosition.y - previousMultiTouchPanPosition.y;
  85. this.camera.inertialPanningX += -moveDeltaX / this.panningSensibility;
  86. this.camera.inertialPanningY += moveDeltaY / this.panningSensibility;
  87. }
  88. }
  89. /**
  90. * Move camera from pinch zoom distances.
  91. * @param previousPinchSquaredDistance
  92. * @param pinchSquaredDistance
  93. */
  94. _computePinchZoom(previousPinchSquaredDistance, pinchSquaredDistance) {
  95. const radius = this.camera.radius || ArcRotateCameraPointersInput.MinimumRadiusForPinch;
  96. if (this.useNaturalPinchZoom) {
  97. this.camera.radius = (radius * Math.sqrt(previousPinchSquaredDistance)) / Math.sqrt(pinchSquaredDistance);
  98. }
  99. else if (this.pinchDeltaPercentage) {
  100. this.camera.inertialRadiusOffset += (pinchSquaredDistance - previousPinchSquaredDistance) * 0.001 * radius * this.pinchDeltaPercentage;
  101. }
  102. else {
  103. this.camera.inertialRadiusOffset +=
  104. (pinchSquaredDistance - previousPinchSquaredDistance) /
  105. ((this.pinchPrecision * (this.pinchInwards ? 1 : -1) * (this.angularSensibilityX + this.angularSensibilityY)) / 2);
  106. }
  107. }
  108. /**
  109. * Called on pointer POINTERMOVE event if only a single touch is active.
  110. * @param point current touch point
  111. * @param offsetX offset on X
  112. * @param offsetY offset on Y
  113. */
  114. onTouch(point, offsetX, offsetY) {
  115. if (this.panningSensibility !== 0 && ((this._ctrlKey && this.camera._useCtrlForPanning) || this._isPanClick)) {
  116. this.camera.inertialPanningX += -offsetX / this.panningSensibility;
  117. this.camera.inertialPanningY += offsetY / this.panningSensibility;
  118. }
  119. else {
  120. this.camera.inertialAlphaOffset -= offsetX / this.angularSensibilityX;
  121. this.camera.inertialBetaOffset -= offsetY / this.angularSensibilityY;
  122. }
  123. }
  124. /**
  125. * Called on pointer POINTERDOUBLETAP event.
  126. */
  127. onDoubleTap() {
  128. if (this.camera.useInputToRestoreState) {
  129. this.camera.restoreState();
  130. }
  131. }
  132. /**
  133. * Called on pointer POINTERMOVE event if multiple touches are active.
  134. * @param pointA point A
  135. * @param pointB point B
  136. * @param previousPinchSquaredDistance distance between points in previous pinch
  137. * @param pinchSquaredDistance distance between points in current pinch
  138. * @param previousMultiTouchPanPosition multi-touch position in previous step
  139. * @param multiTouchPanPosition multi-touch position in current step
  140. */
  141. onMultiTouch(pointA, pointB, previousPinchSquaredDistance, pinchSquaredDistance, previousMultiTouchPanPosition, multiTouchPanPosition) {
  142. if (previousPinchSquaredDistance === 0 && previousMultiTouchPanPosition === null) {
  143. // First time this method is called for new pinch.
  144. // Next time this is called there will be a
  145. // previousPinchSquaredDistance and pinchSquaredDistance to compare.
  146. return;
  147. }
  148. if (pinchSquaredDistance === 0 && multiTouchPanPosition === null) {
  149. // Last time this method is called at the end of a pinch.
  150. return;
  151. }
  152. // Zoom and panning enabled together
  153. if (this.multiTouchPanAndZoom) {
  154. this._computePinchZoom(previousPinchSquaredDistance, pinchSquaredDistance);
  155. this._computeMultiTouchPanning(previousMultiTouchPanPosition, multiTouchPanPosition);
  156. // Zoom and panning enabled but only one at a time
  157. }
  158. else if (this.multiTouchPanning && this.pinchZoom) {
  159. this._twoFingerActivityCount++;
  160. if (this._isPinching ||
  161. (this._twoFingerActivityCount < 20 && Math.abs(Math.sqrt(pinchSquaredDistance) - Math.sqrt(previousPinchSquaredDistance)) > this.camera.pinchToPanMaxDistance)) {
  162. // Since pinch has not been active long, assume we intend to zoom.
  163. this._computePinchZoom(previousPinchSquaredDistance, pinchSquaredDistance);
  164. // Since we are pinching, remain pinching on next iteration.
  165. this._isPinching = true;
  166. }
  167. else {
  168. // Pause between pinch starting and moving implies not a zoom event. Pan instead.
  169. this._computeMultiTouchPanning(previousMultiTouchPanPosition, multiTouchPanPosition);
  170. }
  171. // Panning enabled, zoom disabled
  172. }
  173. else if (this.multiTouchPanning) {
  174. this._computeMultiTouchPanning(previousMultiTouchPanPosition, multiTouchPanPosition);
  175. // Zoom enabled, panning disabled
  176. }
  177. else if (this.pinchZoom) {
  178. this._computePinchZoom(previousPinchSquaredDistance, pinchSquaredDistance);
  179. }
  180. }
  181. /**
  182. * Called each time a new POINTERDOWN event occurs. Ie, for each button
  183. * press.
  184. * @param evt Defines the event to track
  185. */
  186. onButtonDown(evt) {
  187. this._isPanClick = evt.button === this.camera._panningMouseButton;
  188. }
  189. /**
  190. * Called each time a new POINTERUP event occurs. Ie, for each button
  191. * release.
  192. * @param _evt Defines the event to track
  193. */
  194. onButtonUp(_evt) {
  195. this._twoFingerActivityCount = 0;
  196. this._isPinching = false;
  197. }
  198. /**
  199. * Called when window becomes inactive.
  200. */
  201. onLostFocus() {
  202. this._isPanClick = false;
  203. this._twoFingerActivityCount = 0;
  204. this._isPinching = false;
  205. }
  206. }
  207. /**
  208. * The minimum radius used for pinch, to avoid radius lock at 0
  209. */
  210. ArcRotateCameraPointersInput.MinimumRadiusForPinch = 0.001;
  211. __decorate([
  212. serialize()
  213. ], ArcRotateCameraPointersInput.prototype, "buttons", void 0);
  214. __decorate([
  215. serialize()
  216. ], ArcRotateCameraPointersInput.prototype, "angularSensibilityX", void 0);
  217. __decorate([
  218. serialize()
  219. ], ArcRotateCameraPointersInput.prototype, "angularSensibilityY", void 0);
  220. __decorate([
  221. serialize()
  222. ], ArcRotateCameraPointersInput.prototype, "pinchPrecision", void 0);
  223. __decorate([
  224. serialize()
  225. ], ArcRotateCameraPointersInput.prototype, "pinchDeltaPercentage", void 0);
  226. __decorate([
  227. serialize()
  228. ], ArcRotateCameraPointersInput.prototype, "useNaturalPinchZoom", void 0);
  229. __decorate([
  230. serialize()
  231. ], ArcRotateCameraPointersInput.prototype, "pinchZoom", void 0);
  232. __decorate([
  233. serialize()
  234. ], ArcRotateCameraPointersInput.prototype, "panningSensibility", void 0);
  235. __decorate([
  236. serialize()
  237. ], ArcRotateCameraPointersInput.prototype, "multiTouchPanning", void 0);
  238. __decorate([
  239. serialize()
  240. ], ArcRotateCameraPointersInput.prototype, "multiTouchPanAndZoom", void 0);
  241. CameraInputTypes["ArcRotateCameraPointersInput"] = ArcRotateCameraPointersInput;
  242. //# sourceMappingURL=arcRotateCameraPointersInput.js.map