freeCameraMouseWheelInput.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. import { Nullable } from "../../types";
  2. import { serialize } from "../../Misc/decorators";
  3. import { FreeCamera } from "../../Cameras/freeCamera";
  4. import { CameraInputTypes } from "../../Cameras/cameraInputsManager";
  5. import { BaseCameraMouseWheelInput } from "../../Cameras/Inputs/BaseCameraMouseWheelInput";
  6. import { Matrix, Vector3 } from "../../Maths/math.vector";
  7. /**
  8. * Defines the potential axis to be altered in a transform operation.
  9. */
  10. export enum AXIS {
  11. /**
  12. * X axis.
  13. */
  14. X,
  15. /**
  16. * Y axis.
  17. */
  18. Y,
  19. /**
  20. * Z axis.
  21. */
  22. Z
  23. }
  24. /**
  25. * Manage the mouse wheel inputs to control a free camera.
  26. * @see https://doc.babylonjs.com/how_to/customizing_camera_inputs
  27. */
  28. export class FreeCameraMouseWheelInput extends BaseCameraMouseWheelInput {
  29. /**
  30. * Defines the camera the input is attached to.
  31. */
  32. public camera: FreeCamera;
  33. /**
  34. * Gets the class name of the current input.
  35. * @returns the class name
  36. */
  37. public getClassName(): string {
  38. return "FreeCameraMouseWheelInput";
  39. }
  40. /**
  41. * Set which movement axis (relative to camera's orientation) the mouse
  42. * wheel's X axis controls.
  43. * @param axis The axis to be moved. Set null to clear.
  44. */
  45. @serialize()
  46. public set wheelXMoveRelative(axis: Nullable<AXIS>) {
  47. if (axis === null && this._wheelXAction !== this._moveRelative) {
  48. // Attempting to clear different _wheelXAction.
  49. return;
  50. }
  51. this._wheelXAction = this._moveRelative;
  52. this._wheelXActionProperty = axis;
  53. }
  54. /**
  55. * Get the configured movement axis (relative to camera's orientation) the
  56. * mouse wheel's X axis controls.
  57. * @returns The configured axis or null if none.
  58. */
  59. public get wheelXMoveRelative(): Nullable<AXIS> {
  60. if (this._wheelXAction !== this._moveRelative) {
  61. return null;
  62. }
  63. return this._wheelXActionProperty;
  64. }
  65. /**
  66. * Set which movement axis (relative to camera's orientation) the mouse
  67. * wheel's Y axis controls.
  68. * @param axis The axis to be moved. Set null to clear.
  69. */
  70. @serialize()
  71. public set wheelYMoveRelative(axis: Nullable<AXIS>) {
  72. if (axis === null && this._wheelYAction !== this._moveRelative) {
  73. // Attempting to clear different _wheelYAction.
  74. return;
  75. }
  76. this._wheelYAction = this._moveRelative;
  77. this._wheelYActionProperty = axis;
  78. }
  79. /**
  80. * Get the configured movement axis (relative to camera's orientation) the
  81. * mouse wheel's Y axis controls.
  82. * @returns The configured axis or null if none.
  83. */
  84. public get wheelYMoveRelative(): Nullable<AXIS> {
  85. if (this._wheelYAction !== this._moveRelative) {
  86. return null;
  87. }
  88. return this._wheelYActionProperty;
  89. }
  90. /**
  91. * Set which movement axis (relative to camera's orientation) the mouse
  92. * wheel's Z axis controls.
  93. * @param axis The axis to be moved. Set null to clear.
  94. */
  95. @serialize()
  96. public set wheelZMoveRelative(axis: Nullable<AXIS>) {
  97. if (axis === null && this._wheelZAction !== this._moveRelative) {
  98. // Attempting to clear different _wheelZAction.
  99. return;
  100. }
  101. this._wheelZAction = this._moveRelative;
  102. this._wheelZActionProperty = axis;
  103. }
  104. /**
  105. * Get the configured movement axis (relative to camera's orientation) the
  106. * mouse wheel's Z axis controls.
  107. * @returns The configured axis or null if none.
  108. */
  109. public get wheelZMoveRelative(): Nullable<AXIS> {
  110. if (this._wheelZAction !== this._moveRelative) {
  111. return null;
  112. }
  113. return this._wheelZActionProperty;
  114. }
  115. /**
  116. * Set which rotation axis (relative to camera's orientation) the mouse
  117. * wheel's X axis controls.
  118. * @param axis The axis to be moved. Set null to clear.
  119. */
  120. @serialize()
  121. public set wheelXRotateRelative(axis: Nullable<AXIS>) {
  122. if (axis === null && this._wheelXAction !== this._rotateRelative) {
  123. // Attempting to clear different _wheelXAction.
  124. return;
  125. }
  126. this._wheelXAction = this._rotateRelative;
  127. this._wheelXActionProperty = axis;
  128. }
  129. /**
  130. * Get the configured rotation axis (relative to camera's orientation) the
  131. * mouse wheel's X axis controls.
  132. * @returns The configured axis or null if none.
  133. */
  134. public get wheelXRotateRelative(): Nullable<AXIS> {
  135. if (this._wheelXAction !== this._rotateRelative) {
  136. return null;
  137. }
  138. return this._wheelXActionProperty;
  139. }
  140. /**
  141. * Set which rotation axis (relative to camera's orientation) the mouse
  142. * wheel's Y axis controls.
  143. * @param axis The axis to be moved. Set null to clear.
  144. */
  145. @serialize()
  146. public set wheelYRotateRelative(axis: Nullable<AXIS>) {
  147. if (axis === null && this._wheelYAction !== this._rotateRelative) {
  148. // Attempting to clear different _wheelYAction.
  149. return;
  150. }
  151. this._wheelYAction = this._rotateRelative;
  152. this._wheelYActionProperty = axis;
  153. }
  154. /**
  155. * Get the configured rotation axis (relative to camera's orientation) the
  156. * mouse wheel's Y axis controls.
  157. * @returns The configured axis or null if none.
  158. */
  159. public get wheelYRotateRelative(): Nullable<AXIS> {
  160. if (this._wheelYAction !== this._rotateRelative) {
  161. return null;
  162. }
  163. return this._wheelYActionProperty;
  164. }
  165. /**
  166. * Set which rotation axis (relative to camera's orientation) the mouse
  167. * wheel's Z axis controls.
  168. * @param axis The axis to be moved. Set null to clear.
  169. */
  170. @serialize()
  171. public set wheelZRotateRelative(axis: Nullable<AXIS>) {
  172. if (axis === null && this._wheelZAction !== this._rotateRelative) {
  173. // Attempting to clear different _wheelZAction.
  174. return;
  175. }
  176. this._wheelZAction = this._rotateRelative;
  177. this._wheelZActionProperty = axis;
  178. }
  179. /**
  180. * Get the configured rotation axis (relative to camera's orientation) the
  181. * mouse wheel's Z axis controls.
  182. * @returns The configured axis or null if none.
  183. */
  184. public get wheelZRotateRelative(): Nullable<AXIS> {
  185. if (this._wheelZAction !== this._rotateRelative) {
  186. return null;
  187. }
  188. return this._wheelZActionProperty;
  189. }
  190. /**
  191. * Set which movement axis (relative to the scene) the mouse wheel's X axis
  192. * controls.
  193. * @param axis The axis to be moved. Set null to clear.
  194. */
  195. @serialize()
  196. public set wheelXMoveScene(axis: Nullable<AXIS>) {
  197. if (axis === null && this._wheelXAction !== this._rotateRelative) {
  198. // Attempting to clear different _wheelXAction.
  199. return;
  200. }
  201. this._wheelXAction = this._moveScene;
  202. this._wheelXActionProperty = axis;
  203. }
  204. /**
  205. * Get the configured movement axis (relative to the scene) the mouse wheel's
  206. * X axis controls.
  207. * @returns The configured axis or null if none.
  208. */
  209. public get wheelXMoveScene(): Nullable<AXIS> {
  210. if (this._wheelXAction !== this._moveScene) {
  211. return null;
  212. }
  213. return this._wheelXActionProperty;
  214. }
  215. /**
  216. * Set which movement axis (relative to the scene) the mouse wheel's Y axis
  217. * controls.
  218. * @param axis The axis to be moved. Set null to clear.
  219. */
  220. @serialize()
  221. public set wheelYMoveScene(axis: Nullable<AXIS>) {
  222. if (axis === null && this._wheelYAction !== this._rotateRelative) {
  223. // Attempting to clear different _wheelYAction.
  224. return;
  225. }
  226. this._wheelYAction = this._moveScene;
  227. this._wheelYActionProperty = axis;
  228. }
  229. /**
  230. * Get the configured movement axis (relative to the scene) the mouse wheel's
  231. * Y axis controls.
  232. * @returns The configured axis or null if none.
  233. */
  234. public get wheelYMoveScene(): Nullable<AXIS> {
  235. if (this._wheelYAction !== this._moveScene) {
  236. return null;
  237. }
  238. return this._wheelYActionProperty;
  239. }
  240. /**
  241. * Set which movement axis (relative to the scene) the mouse wheel's Z axis
  242. * controls.
  243. * @param axis The axis to be moved. Set null to clear.
  244. */
  245. @serialize()
  246. public set wheelZMoveScene(axis: Nullable<AXIS>) {
  247. if (axis === null && this._wheelZAction !== this._rotateRelative) {
  248. // Attempting to clear different _wheelZAction.
  249. return;
  250. }
  251. this._wheelZAction = this._moveScene;
  252. this._wheelZActionProperty = axis;
  253. }
  254. /**
  255. * Get the configured movement axis (relative to the scene) the mouse wheel's
  256. * Z axis controls.
  257. * @returns The configured axis or null if none.
  258. */
  259. public get wheelZMoveScene(): Nullable<AXIS> {
  260. if (this._wheelZAction !== this._moveScene) {
  261. return null;
  262. }
  263. return this._wheelZActionProperty;
  264. }
  265. /**
  266. * Called for each rendered frame.
  267. */
  268. public checkInputs(): void {
  269. if (this._wheelDeltaX === 0 &&
  270. this._wheelDeltaY === 0 &&
  271. this._wheelDeltaZ == 0) {
  272. return;
  273. }
  274. this._moveRelative.setAll(0);
  275. this._rotateRelative.setAll(0);
  276. this._moveScene.setAll(0);
  277. this._updateCamera(this._wheelDeltaX, this._wheelXAction, this._wheelXActionProperty);
  278. this._updateCamera(this._wheelDeltaY, this._wheelYAction, this._wheelYActionProperty);
  279. this._updateCamera(this._wheelDeltaZ, this._wheelZAction, this._wheelZActionProperty);
  280. if (this.camera.getScene().useRightHandedSystem) {
  281. // TODO: Does this need done for worldUpdate too?
  282. this._moveRelative.z *= -1;
  283. }
  284. // Convert updates relative to camera to world position update.
  285. const cameraTransformMatrix = Matrix.Zero();
  286. this.camera.getViewMatrix().invertToRef(cameraTransformMatrix);
  287. const transformedDirection = Vector3.Zero();
  288. Vector3.TransformNormalToRef(
  289. this._moveRelative, cameraTransformMatrix, transformedDirection);
  290. // Apply updates to camera position.
  291. this.camera.cameraRotation.x += this._rotateRelative.x / 200;
  292. this.camera.cameraRotation.y += this._rotateRelative.y / 200;
  293. this.camera.cameraDirection.addInPlace(transformedDirection);
  294. this.camera.cameraDirection.addInPlace(this._moveScene);
  295. // Call the base class implementation to handle observers and do cleanup.
  296. super.checkInputs();
  297. }
  298. private _moveRelative = Vector3.Zero();
  299. private _rotateRelative = Vector3.Zero();
  300. private _moveScene = Vector3.Zero();
  301. /**
  302. * These are set to the desired default behaviour.
  303. */
  304. private _wheelXAction: Nullable<Vector3> = this._moveRelative;
  305. private _wheelXActionProperty: Nullable<AXIS> = AXIS.X;
  306. private _wheelYAction: Nullable<Vector3> = this._moveRelative;
  307. private _wheelYActionProperty: Nullable<AXIS> = AXIS.Z;
  308. private _wheelZAction: Nullable<Vector3> = null;
  309. private _wheelZActionProperty: Nullable<AXIS> = null;
  310. /**
  311. * Called once per mouse wheel axis. Will update the camera according to any
  312. * configured properties for that axis.
  313. */
  314. private _updateCamera(
  315. value: number, action: Nullable<Vector3>, property: Nullable<Axis>): void {
  316. if (value === 0) {
  317. // Mouse wheel has not moved.
  318. return;
  319. }
  320. if (action === null || property === null) {
  321. // Mouse wheel axis not configured.
  322. return;
  323. }
  324. switch (property) {
  325. case AXIS.X:
  326. action.set(value, 0, 0);
  327. break;
  328. case AXIS.Y:
  329. action.set(0, value, 0);
  330. break;
  331. case AXIS.Z:
  332. action.set(0, 0, value);
  333. break;
  334. }
  335. }
  336. }
  337. (<any>CameraInputTypes)["FreeCameraMouseWheelInput"] = FreeCameraMouseWheelInput;