engine.views.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import { Engine } from "../engine";
  2. import { Camera } from '../../Cameras/camera';
  3. import { Nullable } from '../../types';
  4. import { Scene } from '../../scene';
  5. /**
  6. * Class used to define an additional view for the engine
  7. * @see https://doc.babylonjs.com/how_to/multi_canvases
  8. */
  9. export class EngineView {
  10. /** Defines the canvas where to render the view */
  11. target: HTMLCanvasElement;
  12. /** Defines an optional camera used to render the view (will use active camera else) */
  13. camera?: Camera;
  14. }
  15. declare module "../../Engines/engine" {
  16. export interface Engine {
  17. /**
  18. * Gets or sets the HTML element to use for attaching events
  19. */
  20. inputElement: Nullable<HTMLElement>;
  21. /**
  22. * Gets the current engine view
  23. * @see https://doc.babylonjs.com/how_to/multi_canvases
  24. */
  25. activeView: Nullable<EngineView>;
  26. /** Gets or sets the list of views */
  27. views: EngineView[];
  28. /**
  29. * Register a new child canvas
  30. * @param canvas defines the canvas to register
  31. * @param camera defines an optional camera to use with this canvas (it will overwrite the scene.camera for this view)
  32. * @returns the associated view
  33. */
  34. registerView(canvas: HTMLCanvasElement, camera?: Camera): EngineView;
  35. /**
  36. * Remove a registered child canvas
  37. * @param canvas defines the canvas to remove
  38. * @returns the current engine
  39. */
  40. unRegisterView(canvas: HTMLCanvasElement): Engine;
  41. }
  42. }
  43. Engine.prototype.getInputElement = function(): Nullable<HTMLElement> {
  44. return this.inputElement || this.getRenderingCanvas();
  45. };
  46. Engine.prototype.registerView = function(canvas: HTMLCanvasElement, camera?: Camera): EngineView {
  47. if (!this.views) {
  48. this.views = [];
  49. }
  50. for (var view of this.views) {
  51. if (view.target === canvas) {
  52. return view;
  53. }
  54. }
  55. let masterCanvas = this.getRenderingCanvas();
  56. if (masterCanvas) {
  57. canvas.width = masterCanvas.width;
  58. canvas.height = masterCanvas.height;
  59. }
  60. let newView = {target: canvas, camera: camera};
  61. this.views.push(newView);
  62. if (camera) {
  63. camera.onDisposeObservable.add(() => {
  64. this.unRegisterView(canvas);
  65. });
  66. }
  67. return newView;
  68. };
  69. Engine.prototype.unRegisterView = function(canvas: HTMLCanvasElement): Engine {
  70. if (!this.views) {
  71. return this;
  72. }
  73. for (var view of this.views) {
  74. if (view.target === canvas) {
  75. let index = this.views.indexOf(view);
  76. if (index !== -1) {
  77. this.views.splice(index, 1);
  78. }
  79. break;
  80. }
  81. }
  82. return this;
  83. };
  84. Engine.prototype._renderViews = function() {
  85. if (!this.views) {
  86. return false;
  87. }
  88. let parent = this.getRenderingCanvas();
  89. if (!parent) {
  90. return false;
  91. }
  92. for (var view of this.views) {
  93. let canvas = view.target;
  94. let context = canvas.getContext("2d");
  95. if (!context) {
  96. continue;
  97. }
  98. let camera = view.camera;
  99. let previewCamera: Nullable<Camera> = null;
  100. let scene: Nullable<Scene> = null;
  101. if (camera) {
  102. scene = camera.getScene();
  103. if (scene.activeCameras.length) {
  104. continue;
  105. }
  106. this.activeView = view;
  107. previewCamera = scene.activeCamera;
  108. scene.activeCamera = camera;
  109. }
  110. // Set sizes
  111. if (canvas.clientWidth && canvas.clientHeight) {
  112. canvas.width = canvas.clientWidth;
  113. canvas.height = canvas.clientHeight;
  114. parent.width = canvas.clientWidth;
  115. parent.height = canvas.clientHeight;
  116. this.resize();
  117. }
  118. if (!parent.width || !parent.height) {
  119. return false;
  120. }
  121. // Render the frame
  122. this._renderFrame();
  123. // Copy to target
  124. context.drawImage(parent, 0, 0);
  125. // Restore
  126. if (previewCamera && scene) {
  127. scene.activeCamera = previewCamera;
  128. }
  129. }
  130. this.activeView = null;
  131. return true;
  132. };