@awayjs/view
Version:
View for AwayJS
433 lines (431 loc) • 16.3 kB
JavaScript
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 };