UNPKG

@awayjs/view

Version:
433 lines (431 loc) 16.3 kB
import { __extends } from "tslib"; import { Vector3D, ProjectionEvent, Matrix3D, Rectangle, AssetEvent, PerspectiveProjection, ErrorBase, AssetBase, } from '@awayjs/core'; import { StageEvent, Image2D, ImageCube, ContextGLClearMask, ContextGLProfile, ContextMode, StageManager, } from '@awayjs/stage'; import { ViewEvent } from './events/ViewEvent'; import { ContainerNode } from './partition/ContainerNode'; var View = /** @class */ (function (_super) { __extends(View, _super); function View(projection, stage, forceSoftware, profile, mode, alpha) { if (projection === void 0) { projection = null; } if (stage === void 0) { stage = null; } if (forceSoftware === void 0) { forceSoftware = false; } if (profile === void 0) { profile = ContextGLProfile.BASELINE; } if (mode === void 0) { mode = ContextMode.AUTO; } if (alpha === void 0) { alpha = false; } var _this = _super.call(this) || this; _this._rect = new Rectangle(); _this._backgroundColor = 0; _this._backgroundRed = 0; _this._backgroundGreen = 0; _this._backgroundBlue = 0; _this._focalLength = 1000; _this._pixelRatio = 1; _this._frustumMatrix3D = new Matrix3D(); _this._viewMatrix3D = new Matrix3D(); _this._inverseViewMatrix3D = new Matrix3D(); _this._components = new Array(4); _this._offset = new Vector3D(); _this._scale = new Vector3D(1, 1, 1); _this._frustumMatrix3DDirty = true; _this._viewMatrix3DDirty = true; _this._inverseViewMatrix3DDirty = true; /** * */ _this.backgroundAlpha = 1; /** * */ _this.backgroundDepth = 1; /** * */ _this.backgroundStencil = 0; /** * */ _this.preservePixelRatio = true; /** * */ _this.preserveFocalLength = false; /** * */ _this.preserveDimensions = false; _this._components[0] = _this._offset; _this._components[3] = _this._scale; _this._onInvalidateSizeDelegate = function (event) { return _this._onInvalidateSize(event); }; _this._onInvalidateViewMatrix3DDelegate = function (event) { return _this._onInvalidateViewMatrix3D(event); }; _this._projection = projection || new PerspectiveProjection(); _this._projection.addEventListener(ProjectionEvent.INVALIDATE_VIEW_MATRIX3D, _this._onInvalidateViewMatrix3DDelegate); if (stage) _this._shareContext = true; _this._stage = stage || StageManager.getInstance().getFreeStage(forceSoftware, profile, mode, alpha); _this._stage.addEventListener(StageEvent.INVALIDATE_SIZE, _this._onInvalidateSizeDelegate); _this._updateDimensions(); _this._updateFocalLength(); _this._updatePixelRatio(); return _this; } Object.defineProperty(View.prototype, "shareContext", { /** * */ get: function () { return this._shareContext; }, enumerable: false, configurable: true }); Object.defineProperty(View.prototype, "x", { /** * */ get: function () { if (this._shareContext || this._target) return this._rect.x; return this._stage.x; }, set: function (value) { if (this._shareContext || this._target) { if (this._rect.x == value) return; this._offset.x = (this._rect.x = value) / this._targetWidth; this._invalidateViewMatrix3D(); } else { this._stage.x = value; } }, enumerable: false, configurable: true }); Object.defineProperty(View.prototype, "y", { /** * */ get: function () { if (this._shareContext || this._target) return this._rect.y; return this._stage.y; }, set: function (value) { if (this._shareContext || this._target) { if (this._rect.y == value) return; this._offset.y = (this._rect.y = value) / this._targetHeight; this._invalidateViewMatrix3D(); } else { this._stage.y = value; } }, enumerable: false, configurable: true }); Object.defineProperty(View.prototype, "width", { /** * */ get: function () { return this._rect.width; }, set: function (value) { if (this._rect.width == value) return; this._rect.width = value; if (this._shareContext || this._target) { this._scale.x = value / this._targetWidth; this._updatePixelRatio(); this._invalidateViewMatrix3D(); } else { this._stage.width = value; } this._invalidateSize(); }, enumerable: false, configurable: true }); Object.defineProperty(View.prototype, "height", { /** * */ get: function () { return this._rect.height; }, set: function (value) { if (this._rect.height == value) return; this._rect.height = value; if (this._shareContext || this._target) { this._scale.y = value / this._targetHeight; this._updateFocalLength(); this._updatePixelRatio(); this._invalidateViewMatrix3D(); } else { this._stage.height = value; } this._invalidateSize(); }, enumerable: false, configurable: true }); Object.defineProperty(View.prototype, "backgroundColor", { /** * */ get: function () { return this._backgroundColor; }, set: function (value) { if (this._backgroundColor == value) return; this._backgroundColor = value; this._backgroundRed = ((value >> 16) & 0xff) / 0xff; this._backgroundGreen = ((value >> 8) & 0xff) / 0xff; this._backgroundBlue = (value & 0xff) / 0xff; }, enumerable: false, configurable: true }); Object.defineProperty(View.prototype, "focalLength", { /** * */ get: function () { return this._focalLength; }, set: function (value) { if (this._focalLength == value) return; this._focalLength = value; this._updateFocalLength(); }, enumerable: false, configurable: true }); Object.defineProperty(View.prototype, "pixelRatio", { /** * */ get: function () { return this._pixelRatio; }, set: function (value) { if (this._pixelRatio == value) return; this._pixelRatio = value; this._updatePixelRatio(); }, enumerable: false, configurable: true }); Object.defineProperty(View.prototype, "projection", { get: function () { return this._projection; }, set: function (value) { if (value == null) throw new ErrorBase('projection cannot be null'); if (this._projection == value) return; this._projection.removeEventListener(ProjectionEvent.INVALIDATE_VIEW_MATRIX3D, this._onInvalidateViewMatrix3DDelegate); this._projection = value; this._projection.addEventListener(ProjectionEvent.INVALIDATE_VIEW_MATRIX3D, this._onInvalidateViewMatrix3DDelegate); this._invalidateViewMatrix3D(); }, enumerable: false, configurable: true }); Object.defineProperty(View.prototype, "target", { get: function () { return this._target; }, set: function (value) { if (this._target == value) return; this._updateTarget(value); }, enumerable: false, configurable: true }); Object.defineProperty(View.prototype, "stage", { get: function () { return this._stage; }, enumerable: false, configurable: true }); Object.defineProperty(View.prototype, "frustumMatrix3D", { get: function () { if (this._frustumMatrix3DDirty) { this._frustumMatrix3DDirty = false; this._frustumMatrix3D.recompose(this._components); this._frustumMatrix3D.prepend(this._projection.frustumMatrix3D); } return this._frustumMatrix3D; }, enumerable: false, configurable: true }); Object.defineProperty(View.prototype, "viewMatrix3D", { get: function () { if (this._viewMatrix3DDirty) { this._viewMatrix3DDirty = false; this._viewMatrix3D.recompose(this._components); this._viewMatrix3D.prepend(this._projection.viewMatrix3D); } return this._viewMatrix3D; }, enumerable: false, configurable: true }); Object.defineProperty(View.prototype, "inverseViewMatrix3D", { get: function () { if (this._inverseViewMatrix3DDirty) { this._inverseViewMatrix3DDirty = false; this._inverseViewMatrix3D.copyFrom(this.viewMatrix3D); this._inverseViewMatrix3D.invert(); } return this._inverseViewMatrix3D; }, enumerable: false, configurable: true }); View.prototype.requestAbstraction = function (_asset) { return View._store.length ? View._store.pop() : new ContainerNode(); }; View.prototype.storeAbstraction = function (abstraction) { View._store.push(abstraction); }; View.prototype.getNode = function (entity) { return entity.getAbstraction(this); }; View.prototype.clear = function (enableClear, enableDepthAndStencil, surfaceSelector, mipmapSelector, clearMaskSelector) { if (enableClear === void 0) { enableClear = true; } if (enableDepthAndStencil === void 0) { enableDepthAndStencil = true; } if (surfaceSelector === void 0) { surfaceSelector = 0; } if (mipmapSelector === void 0) { mipmapSelector = 0; } if (clearMaskSelector === void 0) { clearMaskSelector = ContextGLClearMask.ALL; } this._stage.setRenderTarget(this._target, enableDepthAndStencil, surfaceSelector, mipmapSelector); //TODO: make scissor compatible with image targets this._stage.setScissor((this._target == null) ? this._rect : null); if (enableClear) { this._stage.clear(this._backgroundRed, this._backgroundGreen, this._backgroundBlue, this.backgroundAlpha, this.backgroundDepth, this.backgroundStencil, clearMaskSelector); } }; View.prototype.present = function () { if (!this._shareContext && this._target == null) this._stage.present(); }; /* */ View.prototype.project = function (position, target) { if (target === void 0) { target = null; } target = this._projection.project(position, target); target.x = (target.x + 1) * this.width / 2; target.y = (target.y + 1) * this.height / 2; return target; }; View.prototype.unproject = function (sX, sY, sZ, target) { if (target === void 0) { target = null; } return this._projection.unproject(2 * sX / this.width - 1, 2 * sY / this.height - 1, sZ, target); }; View.prototype.dispose = function () { if (this._target) { this._target.removeEventListener(AssetEvent.INVALIDATE, this._onInvalidateSizeDelegate); this._target = null; } else { this._stage.removeEventListener(StageEvent.INVALIDATE_SIZE, this._onInvalidateSizeDelegate); if (!this._shareContext && this._target == null) this._stage.dispose(); this._stage = null; } if (this._projection) { this._projection.removeEventListener(ProjectionEvent.INVALIDATE_VIEW_MATRIX3D, this._onInvalidateViewMatrix3DDelegate); this._projection = null; } }; View.prototype._onInvalidateSize = function (event) { this._updateDimensions(); this._updateFocalLength(); this._updatePixelRatio(); if (!this.preserveDimensions || (!this._shareContext && this._target == null)) this._invalidateSize(); }; View.prototype._onInvalidateViewMatrix3D = function (event) { this._invalidateViewMatrix3D(); }; View.prototype._updateTarget = function (value) { if (this._target) this._target.removeEventListener(AssetEvent.INVALIDATE, this._onInvalidateSizeDelegate); else this._stage.removeEventListener(StageEvent.INVALIDATE_SIZE, this._onInvalidateSizeDelegate); this._target = value; if (this._target) this._target.addEventListener(AssetEvent.INVALIDATE, this._onInvalidateSizeDelegate); else this._stage.addEventListener(StageEvent.INVALIDATE_SIZE, this._onInvalidateSizeDelegate); this._updateDimensions(); this._updateFocalLength(); this._updatePixelRatio(); if (!this.preserveDimensions || (!this._shareContext && this._target == null)) this._invalidateSize(); }; View.prototype._updateDimensions = function () { if (this._target) { if (this._target instanceof Image2D) { this._targetWidth = this._target.width; this._targetHeight = this._target.height; } else if (this._target instanceof ImageCube) { this._targetWidth = this._target.size; this._targetHeight = this._target.size; } } else { this._targetWidth = this._stage.width; this._targetHeight = this._stage.height; } if (this.preserveDimensions && (this._shareContext || this._target)) { this._offset.x = this._rect.x / this._targetWidth; this._offset.y = this._rect.y / this._targetHeight; this._scale.x = this._rect.width / this._targetWidth; this._scale.y = this._rect.height / this._targetHeight; } else { this._rect.x = this._offset.x * this._targetWidth; this._rect.y = this._offset.y * this._targetHeight; this._rect.width = this._scale.x * this._targetWidth; this._rect.height = this._scale.y * this._targetHeight; } }; View.prototype._updateFocalLength = function () { if (this.preserveFocalLength) this.projection.scale = this._focalLength / this._rect.height; else this._focalLength = this._projection.scale * this._rect.height; }; View.prototype._updatePixelRatio = function () { if (this.preservePixelRatio) this._projection.ratio = this._pixelRatio * this._rect.width / this._rect.height; else this._pixelRatio = this._projection.ratio * this._rect.height / this._rect.width; }; View.prototype._invalidateViewMatrix3D = function () { this._frustumMatrix3DDirty = true; this._viewMatrix3DDirty = true; this._inverseViewMatrix3DDirty = true; this.dispatchEvent(new ViewEvent(ViewEvent.INVALIDATE_VIEW_MATRIX3D, this)); }; View.prototype._invalidateSize = function () { this.dispatchEvent(new ViewEvent(ViewEvent.INVALIDATE_SIZE, this)); }; View._store = []; return View; }(AssetBase)); export { View };