babylon.cameraInputsManager.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. module BABYLON {
  2. export var CameraInputTypes = {};
  3. export interface ICameraInput<TCamera extends BABYLON.Camera> {
  4. camera: TCamera;
  5. getTypeName(): string;
  6. getSimpleName(): string;
  7. attachControl: (element: HTMLElement, noPreventDefault?: boolean) => void;
  8. detachControl: (element: HTMLElement) => void;
  9. checkInputs?: () => void;
  10. }
  11. export interface CameraInputsMap<TCamera extends BABYLON.Camera> {
  12. [name: string]: ICameraInput<TCamera>;
  13. [idx: number]: ICameraInput<TCamera>;
  14. }
  15. export class CameraInputsManager<TCamera extends BABYLON.Camera> {
  16. attached: CameraInputsMap<TCamera>;
  17. attachedElement: HTMLElement;
  18. camera: TCamera;
  19. checkInputs: () => void;
  20. constructor(camera: TCamera) {
  21. this.attached = {};
  22. this.camera = camera;
  23. this.checkInputs = () => { };
  24. }
  25. public add(input: ICameraInput<TCamera>) {
  26. var type = input.getSimpleName();
  27. if (this.attached[type]) {
  28. Tools.Warn("camera input of type " + type + " already exists on camera");
  29. return;
  30. }
  31. this.attached[type] = input;
  32. input.camera = this.camera;
  33. //for checkInputs, we are dynamically creating a function
  34. //the goal is to avoid the performance penalty of looping for inputs in the render loop
  35. if (input.checkInputs) {
  36. this.checkInputs = this._addCheckInputs(input.checkInputs.bind(input));
  37. }
  38. if (this.attachedElement){
  39. input.attachControl(this.attachedElement);
  40. }
  41. }
  42. public remove(inputToRemove: ICameraInput<TCamera>) {
  43. for (var cam in this.attached) {
  44. var input = this.attached[cam];
  45. if (input === inputToRemove) {
  46. input.detachControl(this.attachedElement);
  47. delete this.attached[cam];
  48. }
  49. }
  50. }
  51. public removeByType(inputType: string) {
  52. for (var cam in this.attached) {
  53. var input = this.attached[cam];
  54. if (input.getTypeName() === inputType) {
  55. input.detachControl(this.attachedElement);
  56. delete this.attached[cam];
  57. }
  58. }
  59. }
  60. private _addCheckInputs(fn) {
  61. var current = this.checkInputs;
  62. return () => {
  63. current();
  64. fn();
  65. }
  66. }
  67. public attachElement(element: HTMLElement, noPreventDefault?: boolean) {
  68. this.attachedElement = element;
  69. for (var cam in this.attached) {
  70. var input = this.attached[cam];
  71. this.attached[cam].attachControl(element, noPreventDefault);
  72. }
  73. }
  74. public detachElement(element: HTMLElement) {
  75. for (var cam in this.attached) {
  76. var input = this.attached[cam];
  77. this.attached[cam].detachControl(element);
  78. }
  79. }
  80. public rebuildInputCheck(element: HTMLElement) {
  81. this.checkInputs = () => { };
  82. for (var cam in this.attached) {
  83. var input = this.attached[cam];
  84. if (input.checkInputs) {
  85. this.checkInputs = this._addCheckInputs(input.checkInputs.bind(input));
  86. }
  87. }
  88. }
  89. public clear() {
  90. if (this.attachedElement) {
  91. this.detachElement(this.attachedElement);
  92. }
  93. this.attached = {};
  94. this.attachedElement = null;
  95. this.checkInputs = () => { };
  96. }
  97. public serialize(serializedCamera) {
  98. var inputs = {};
  99. for (var cam in this.attached) {
  100. var input = this.attached[cam];
  101. var res = SerializationHelper.Serialize(input, serializedCamera);
  102. inputs[input.getTypeName()] = res;
  103. }
  104. serializedCamera.inputsmgr = inputs;
  105. }
  106. public parse(parsedCamera) {
  107. var parsedInputs = parsedCamera.inputsmgr;
  108. if (parsedInputs) {
  109. this.clear();
  110. for (var n in parsedInputs) {
  111. var construct = CameraInputTypes[n];
  112. if (construct) {
  113. var parsedinput = parsedInputs[n];
  114. var input = SerializationHelper.Parse(() => { return new construct() }, parsedinput, null);
  115. this.add(input as any);
  116. }
  117. }
  118. } else {
  119. //2016-03-08 this part is for managing backward compatibility
  120. for (var n in this.attached) {
  121. var construct = CameraInputTypes[this.attached[n].getTypeName()];
  122. if (construct) {
  123. var input = SerializationHelper.Parse(() => { return new construct() }, parsedCamera, null);
  124. this.add(input as any);
  125. }
  126. }
  127. }
  128. }
  129. }
  130. }