/home/lindsay/xeolabs/xeogl-next/xeogl/src/viewport/viewport.js
API Docs for:

File: /home/lindsay/xeolabs/xeogl-next/xeogl/src/viewport/viewport.js

  1. /**
  2. A **Viewport** controls the canvas viewport for a {{#crossLink "Scene"}}{{/crossLink}}.
  3.  
  4. <a href="../../examples/#effects_stereo_custom"><img src="../../../assets/images/screenshots/StereoEffect.png"></img></a>
  5.  
  6. ## Overview
  7.  
  8. * One Viewport per scene.
  9. * You can configure a Scene to render multiple times per frame, while setting the Viewport to different extents on each render.
  10. * Make a Viewport automatically size to its {{#crossLink "Scene"}}Scene's{{/crossLink}} {{#crossLink "Canvas"}}{{/crossLink}}
  11. by setting its {{#crossLink "Viewport/autoBoundary:property"}}{{/crossLink}} property ````true```` (default is ````false````).
  12.  
  13. ## Examples
  14.  
  15. * [Stereo effect using alternating viewports](../../examples/#effects_stereo_custom)
  16.  
  17. ## Usage
  18.  
  19. Configuring the Scene to render twice on each frame, each time to a separate viewport:
  20.  
  21. ````Javascript
  22. // Load glTF model
  23. var model = new xeogl.GLTFModel({
  24. src: "models/gltf/GearboxAssy/glTF-MaterialsCommon/GearboxAssy.gltf"
  25. });
  26.  
  27. var scene = model.scene;
  28. var viewport = scene.viewport;
  29.  
  30. // Configure Scene to render twice for each frame
  31. scene.passes = 2; // Default is 1
  32. scene.clearEachPass = false; // Default is false
  33.  
  34. // Render to a separate viewport on each render
  35.  
  36. var viewport = scene.viewport;
  37. viewport.autoBoundary = false;
  38.  
  39. scene.on("rendering", function (e) {
  40. switch (e.pass) {
  41. case 0:
  42. viewport.boundary = [0, 0, 200, 200]; // xmin, ymin, width, height
  43. break;
  44.  
  45. case 1:
  46. viewport.boundary = [200, 0, 200, 200];
  47. break;
  48. }
  49. });
  50. ````
  51.  
  52. @class Viewport
  53. @module xeogl
  54. @submodule rendering
  55. @constructor
  56. @param [owner] {Component} Owner component. When destroyed, the owner will destroy this component as well. Creates this component within the default {{#crossLink "Scene"}}{{/crossLink}} when omitted.
  57. @param [cfg] {*} Viewport configuration
  58. @param [cfg.id] {String} Optional ID, unique among all components in the parent
  59. {{#crossLink "Scene"}}Scene{{/crossLink}}, generated automatically when omitted.
  60. @param [cfg.meta] {String:Object} Optional map of user-defined metadata to attach to this Viewport.
  61. @param [cfg.boundary] {Array of Number} Canvas-space Viewport boundary, given as
  62. (min, max, width, height). Defaults to the size of the parent
  63. {{#crossLink "Scene"}}Scene's{{/crossLink}} {{#crossLink "Canvas"}}{{/crossLink}}.
  64. @param [cfg.autoBoundary=false] {Boolean} Indicates whether this Viewport's {{#crossLink "Viewport/boundary:property"}}{{/crossLink}}
  65. automatically synchronizes with the size of the parent {{#crossLink "Scene"}}Scene's{{/crossLink}} {{#crossLink "Canvas"}}{{/crossLink}}.
  66.  
  67. @extends Component
  68. */
  69. import {Component} from '../component.js';
  70. import {State} from '../renderer/state.js';
  71. import {componentClasses} from "./../componentClasses.js";
  72.  
  73. const type = "xeogl.Viewport";
  74.  
  75. class Viewport extends Component {
  76.  
  77. /**
  78. JavaScript class name for this Component.
  79.  
  80. For example: "xeogl.AmbientLight", "xeogl.MetallicMaterial" etc.
  81.  
  82. @property type
  83. @type String
  84. @final
  85. */
  86. get type() {
  87. return type;
  88. }
  89.  
  90. init(cfg) {
  91.  
  92. super.init(cfg);
  93.  
  94. this._state = new State({
  95. boundary: [0, 0, 100, 100]
  96. });
  97.  
  98. this.boundary = cfg.boundary;
  99. this.autoBoundary = cfg.autoBoundary;
  100. }
  101.  
  102.  
  103. /**
  104. The canvas-space boundary of this Viewport, indicated as [min, max, width, height].
  105.  
  106. Defaults to the size of the parent
  107. {{#crossLink "Scene"}}Scene's{{/crossLink}} {{#crossLink "Canvas"}}{{/crossLink}}.
  108.  
  109. Ignores attempts to set value when {{#crossLink "Viewport/autoBoundary:property"}}{{/crossLink}} is ````true````.
  110.  
  111. Fires a {{#crossLink "Viewport/boundary:event"}}{{/crossLink}} event on change.
  112.  
  113. @property boundary
  114. @default [size of Scene Canvas]
  115. @type {Array of Number}
  116. */
  117. set boundary(value) {
  118.  
  119. if (this._autoBoundary) {
  120. return;
  121. }
  122.  
  123. if (!value) {
  124.  
  125. const canvasBoundary = this.scene.canvas.boundary;
  126.  
  127. const width = canvasBoundary[2];
  128. const height = canvasBoundary[3];
  129.  
  130. value = [0, 0, width, height];
  131. }
  132.  
  133. this._state.boundary = value;
  134.  
  135. this._renderer.imageDirty();
  136.  
  137. /**
  138. Fired whenever this Viewport's {{#crossLink "Viewport/boundary:property"}}{{/crossLink}} property changes.
  139.  
  140. @event boundary
  141. @param value {Boolean} The property's new value
  142. */
  143. this.fire("boundary", this._state.boundary);
  144. }
  145.  
  146. get boundary() {
  147. return this._state.boundary;
  148. }
  149.  
  150. /**
  151. Indicates whether this Viewport's {{#crossLink "Viewport/boundary:property"}}{{/crossLink}} automatically
  152. synchronizes with the size of the parent {{#crossLink "Scene"}}Scene's{{/crossLink}} {{#crossLink "Canvas"}}{{/crossLink}}.
  153.  
  154. When set true, then this Viewport will fire a {{#crossLink "Viewport/boundary/event"}}{{/crossLink}} whenever
  155. the {{#crossLink "Canvas"}}{{/crossLink}} resizes. Also fires that event as soon as this ````autoBoundary````
  156. property is changed.
  157.  
  158. Fires a {{#crossLink "Viewport/autoBoundary:event"}}{{/crossLink}} event on change.
  159.  
  160. @property autoBoundary
  161. @default false
  162. @type Boolean
  163. */
  164. set autoBoundary(value) {
  165.  
  166. value = !!value;
  167.  
  168. if (value === this._autoBoundary) {
  169. return;
  170. }
  171.  
  172. this._autoBoundary = value;
  173.  
  174. if (this._autoBoundary) {
  175. this._onCanvasSize = this.scene.canvas.on("boundary",
  176. function (boundary) {
  177.  
  178. const width = boundary[2];
  179. const height = boundary[3];
  180.  
  181. this._state.boundary = [0, 0, width, height];
  182.  
  183. this._renderer.imageDirty();
  184.  
  185. /**
  186. Fired whenever this Viewport's {{#crossLink "Viewport/boundary:property"}}{{/crossLink}} property changes.
  187.  
  188. @event boundary
  189. @param value {Boolean} The property's new value
  190. */
  191. this.fire("boundary", this._state.boundary);
  192.  
  193. }, this);
  194.  
  195. } else if (this._onCanvasSize) {
  196. this.scene.canvas.off(this._onCanvasSize);
  197. this._onCanvasSize = null;
  198. }
  199.  
  200. /**
  201. Fired whenever this Viewport's {{#crossLink "autoBoundary/autoBoundary:property"}}{{/crossLink}} property changes.
  202.  
  203. @event autoBoundary
  204. @param value The property's new value
  205. */
  206. this.fire("autoBoundary", this._autoBoundary);
  207. }
  208.  
  209. get autoBoundary() {
  210. return this._autoBoundary;
  211. }
  212.  
  213. _getState() {
  214. return this._state;
  215. }
  216.  
  217. destroy() {
  218. super.destroy();
  219. this._state.destroy();
  220. }
  221. }
  222.  
  223. componentClasses[type] = Viewport;
  224.  
  225. export{Viewport};