babylon.cameraInputsManager.ts 4.6 KB

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