UNPKG

@awayjs/view

Version:
628 lines (627 loc) 27 kB
import { __extends } from "tslib"; import { Vector3D, AbstractionBase, Matrix3D, ColorTransform, Point, Transform, PerspectiveProjection, CoordinateSystem, } from '@awayjs/core'; import { HierarchicalProperty } from '../base/HierarchicalProperty'; import { BlendMode, Settings as StageSettings, isNativeBlend } from '@awayjs/stage'; import { AlignmentMode } from '../base/AlignmentMode'; import { OrientationMode } from '../base/OrientationMode'; import { ContainerNodeEvent } from '../events/ContainerNodeEvent'; import { View } from '../View'; var ContainerNode = /** @class */ (function (_super) { __extends(ContainerNode, _super); function ContainerNode() { var _this = _super !== null && _super.apply(this, arguments) || this; _this._renderToImage = false; _this._position = new Vector3D(); _this._matrix3D = new Matrix3D(); _this._inverseMatrix3DDirty = true; _this._maskDisabled = false; _this._colorTransformDisabled = false; _this._transformDisabled = false; _this._maskId = -1; _this._masks = []; _this._childNodes = new Array(); _this._numChildNodes = 0; _this._hierarchicalPropsDirty = HierarchicalProperty.ALL; return _this; } Object.defineProperty(ContainerNode.prototype, "parent", { get: function () { return this._parent; }, enumerable: false, configurable: true }); Object.defineProperty(ContainerNode.prototype, "numChildNodes", { get: function () { return this._numChildNodes; }, enumerable: false, configurable: true }); Object.defineProperty(ContainerNode.prototype, "container", { get: function () { return this._asset; }, enumerable: false, configurable: true }); Object.defineProperty(ContainerNode.prototype, "pickObjectNode", { get: function () { if (this._pickObject != this._asset.pickObject) { this._pickObject = this._asset.pickObject; if (this._pickObject) { this._pickObjectNode = this._pickObject.getAbstraction(this._pool); if (this._pickObject.pickObjectFromTimeline) this._pickObjectNode.setParent(this); } else { this._pickObjectNode.setParent(null); this._pickObjectNode = null; } } return this._pickObjectNode; }, enumerable: false, configurable: true }); Object.defineProperty(ContainerNode.prototype, "renderToImage", { get: function () { var _a = this._asset, blendMode = _a.blendMode, filters = _a.filters, cacheAsBitmap = _a.cacheAsBitmap; var renderToImage = this.isRenderable() && (cacheAsBitmap || filters && filters.length > 0 || (blendMode && blendMode !== BlendMode.LAYER && blendMode !== BlendMode.NORMAL && (StageSettings.USE_NON_NATIVE_BLEND || isNativeBlend(blendMode)))); if (this._renderToImage !== renderToImage) { this._renderToImage = renderToImage; if (!this._renderToImage) this.clearLocalNode(); } return this._renderToImage; }, enumerable: false, configurable: true }); Object.defineProperty(ContainerNode.prototype, "boundsVisible", { get: function () { return false; }, enumerable: false, configurable: true }); Object.defineProperty(ContainerNode.prototype, "view", { get: function () { return this._pool; }, enumerable: false, configurable: true }); Object.defineProperty(ContainerNode.prototype, "colorTransformDisabled", { get: function () { return this._colorTransformDisabled; }, /** * Allow disable/enable colorTransform for this node independent of transform, this required for cache phase * @param value */ set: function (value) { this._colorTransformDisabled = value; }, enumerable: false, configurable: true }); Object.defineProperty(ContainerNode.prototype, "maskDisabled", { get: function () { return this._maskDisabled; }, set: function (value) { this._maskDisabled = value; }, enumerable: false, configurable: true }); Object.defineProperty(ContainerNode.prototype, "transformDisabled", { get: function () { return this._transformDisabled; }, set: function (value) { if (this._transformDisabled == value) return; this._maskDisabled = value; this._transformDisabled = value; this._colorTransformDisabled = value; if (this._transformDisabled) { this._activeTransform = ContainerNode._nullTransform; } else { this._activeTransform = this._asset.transform; } }, enumerable: false, configurable: true }); ContainerNode.prototype.getScale9Container = function () { var _a; if (this._hierarchicalPropsDirty & HierarchicalProperty.SCALE9) { this._scale9Container = this._asset.scale9Grid ? this._asset : (_a = this._parent) === null || _a === void 0 ? void 0 : _a.getScale9Container(); this._hierarchicalPropsDirty ^= HierarchicalProperty.SCALE9; } return this._scale9Container; }; /** * */ ContainerNode.prototype.getPosition = function () { if (this._positionDirty) { if (this._asset._registrationMatrix3D && this._asset.alignmentMode === AlignmentMode.REGISTRATION_POINT) { this._position.x = -this._asset._registrationMatrix3D._rawData[12]; this._position.y = -this._asset._registrationMatrix3D._rawData[13]; this._position.z = -this._asset._registrationMatrix3D._rawData[14]; this._position = this.getMatrix3D().transformVector(this._position, this._position); /* this._position.decrementBy( new Vector3D( this._registrationPoint.x*this._scaleX, this._registrationPoint.y*this._scaleY, this._registrationPoint.z*this._scaleZ)); */ } else { this.getMatrix3D().copyColumnTo(3, this._position); } this._positionDirty = false; } return this._position; }; /** * */ ContainerNode.prototype.getInverseMatrix3D = function () { if (this._inverseMatrix3DDirty) { if (!this._inverseMatrix3D) this._inverseMatrix3D = new Matrix3D(); this._inverseMatrix3DDirty = false; this._inverseMatrix3D.copyFrom(this.getMatrix3D()); this._inverseMatrix3D.invert(); } return this._inverseMatrix3D || (this._inverseMatrix3D = new Matrix3D()); }; ContainerNode.prototype.getMatrix3D = function () { if (this._hierarchicalPropsDirty & HierarchicalProperty.SCENE_TRANSFORM) { this._matrix3D.copyFrom(this._activeTransform.matrix3D); if (!this._transformDisabled) { if (this._asset._registrationMatrix3D) { this._matrix3D.prepend(this._asset._registrationMatrix3D); if (this._asset.alignmentMode != AlignmentMode.REGISTRATION_POINT) { this._matrix3D.appendTranslation(-this._asset._registrationMatrix3D._rawData[12] * this._activeTransform.scale.x, -this._asset._registrationMatrix3D._rawData[13] * this._activeTransform.scale.y, -this._asset._registrationMatrix3D._rawData[14] * this._activeTransform.scale.z); } } if (this._parent) this._matrix3D.append(this._parent.getMatrix3D()); // scrollRect-masks are childs of the object that have the scrollRect applied // to support scrolling we need to: // - move objects with scrollRect by negative scrollRect position // - move scrollRect-masks by positive scrollRect position if (!this._asset.maskMode && this._asset.scrollRect) this._matrix3D.prependTranslation(-this._asset.scrollRect.x, -this._asset.scrollRect.y, 0); else if (this._asset.maskMode && this._asset.scrollRect) this._matrix3D.prependTranslation(this._asset.scrollRect.x, this._asset.scrollRect.y, 0); } this._hierarchicalPropsDirty ^= HierarchicalProperty.SCENE_TRANSFORM; //TODO: refactor controller API if (this._asset['_iController']) this._asset['_iController'].updateController(); } return this._matrix3D; }; /** * */ ContainerNode.prototype.getRenderMatrix3D = function (cameraTransform) { if (this._asset.orientationMode == OrientationMode.CAMERA_PLANE) { var comps = cameraTransform.decompose(); comps[0].copyFrom(this.getPosition()); comps[3].copyFrom(this._activeTransform.scale); (this._orientationMatrix || (this._orientationMatrix = new Matrix3D())).recompose(comps); //add in case of registration point if (this._asset._registrationMatrix3D) { this._orientationMatrix.prepend(this._asset._registrationMatrix3D); if (this._asset.alignmentMode != AlignmentMode.REGISTRATION_POINT) this._orientationMatrix.appendTranslation(-this._asset._registrationMatrix3D._rawData[12] * this._activeTransform.scale.x, -this._asset._registrationMatrix3D._rawData[13] * this._activeTransform.scale.y, -this._asset._registrationMatrix3D._rawData[14] * this._activeTransform.scale.z); } return this._orientationMatrix; } return this.getMatrix3D(); }; ContainerNode.prototype.getColorTransform = function () { if (this._colorTransformDisabled) { return ContainerNode._nullColorTransform; } if (this._hierarchicalPropsDirty & HierarchicalProperty.COLOR_TRANSFORM) { this._hierarchicalPropsDirty ^= HierarchicalProperty.COLOR_TRANSFORM; if (this._colorTransformDisabled) { return ContainerNode._nullColorTransform; } if (!this._colorTransform) this._colorTransform = new ColorTransform(); if (this._parent && this._parent.getColorTransform()) { this._colorTransform.copyFrom(this._parent.getColorTransform()); // we MUST prepend real transform in cached phase, but reset in cached image render phase this._colorTransform.prepend(this._asset.transform.colorTransform); } else { this._colorTransform.copyFrom(this._asset.transform.colorTransform); } /* // if we will use getter - it return empty blend in USE_UNSAFE_BLEND = false if ((<any> (<IContainer> this._asset))._blendMode === BlendMode.OVERLAY) { // apply 0.5 alpha for object with `overlay` because we not support it now this._colorTransform.alphaMultiplier *= 0.5; }*/ } return this._colorTransform || ContainerNode._nullColorTransform; }; /** * * @returns {number} */ ContainerNode.prototype.getMaskId = function () { if (this._hierarchicalPropsDirty & HierarchicalProperty.MASK_ID) { this._maskId = (this._asset.maskId != -1) ? this._asset.maskId : (this._parent) ? this._parent.getMaskId() : -1; this._hierarchicalPropsDirty ^= HierarchicalProperty.MASK_ID; } return this._maskId; }; ContainerNode.prototype.getMasks = function (update) { if (update === void 0) { update = false; } if (!update) { return this._masks; } if (this._asset.masks) { var len = this._asset.masks.length; this._masks.length = len; for (var i = 0; i < len; i++) { this._masks[i] = this._pool.getNode(this._asset.masks[i]); } } else { this._masks.length = 0; } return this._masks; }; ContainerNode.prototype.getMaskOwners = function () { var _a; if (this._hierarchicalPropsDirty & HierarchicalProperty.MASKS) { var masks = this.getMasks(true); this._maskOwners = this._maskDisabled ? null : (((_a = this._parent) === null || _a === void 0 ? void 0 : _a.getMaskOwners()) && this.getMaskId() == -1) ? masks.length ? this._parent.getMaskOwners().concat([this]) : this._parent.getMaskOwners().concat() : masks.length ? [this] : null; this._hierarchicalPropsDirty ^= HierarchicalProperty.MASKS; } return this._maskOwners; }; /** * Converts the `point` object from the Stage(global) coordinates to the * display object's(local) coordinates. * * To use this method, first create an instance of the Point class. The _x_ * and _y_ values that you assign represent global coordinates because they * relate to the origin(0,0) of the main display area. Then pass the Point * instance as the parameter to the `globalToLocal()` method. The method * returns a new Point object with _x_ and _y_ values that relate to the * origin of the display object instead of the origin of the Stage. * */ ContainerNode.prototype.globalToLocal = function (point, target) { if (target === void 0) { target = null; } var tmp = ContainerNode._tempVector3D; tmp.setTo(point.x, point.y, 0); var pos = this.getInverseMatrix3D().transformVector(tmp, tmp); if (!target) { target = new Point(); } target.x = pos.x; target.y = pos.y; return target; }; /** * Converts a two-dimensional point from the Scene(global) coordinates to a * three-dimensional display object's(local) coordinates. * * <p>To use this method, first create an instance of the Vector3D class. The x, * y and z values that you assign to the Vector3D object represent global * coordinates because they are relative to the origin(0,0,0) of the scene. Then * pass the Vector3D object to the <code>globalToLocal3D()</code> method as the * <code>position</code> parameter. * The method returns three-dimensional coordinates as a Vector3D object * containing <code>x</code>, <code>y</code>, and <code>z</code> values that * are relative to the origin of the three-dimensional display object.</p> * */ ContainerNode.prototype.globalToLocal3D = function (position) { return this.getInverseMatrix3D().transformVector(position); }; /** * Converts the `point` object from the display object's(local) coordinates * to the Stage(global) coordinates. * * This method allows you to convert any given _x_ and _y_ coordinates from * values that are relative to the origin(0,0) of a specific display * object(local coordinates) to values that are relative to the origin of * the Stage(global coordinates). * * To use this method, first create an instance of the Point class. The _x_ * and _y_ values that you assign represent local coordinates because they * relate to the origin of the display object. * * You then pass the Point instance that you created as the parameter to the * `localToGlobal()` method. The method returns a new Point object with _x_ * and _y_ values that relate to the origin of the Stage instead of the * origin of the display object. * * @param point The name or identifier of a point created with the Point * class, specifying the _x_ and _y_ coordinates as properties. * @param target Result point * @return A Point object with coordinates relative to the Stage. */ ContainerNode.prototype.localToGlobal = function (point, target) { if (target === void 0) { target = null; } var tmp = ContainerNode._tempVector3D; tmp.setTo(point.x, point.y, 0); var pos = this.getMatrix3D().transformVector(tmp, tmp); if (!target) { target = new Point(); } target.x = pos.x; target.y = pos.y; return target; }; ContainerNode.prototype.getBoundsPrimitive = function (_pickGroup) { return null; }; ContainerNode.prototype.init = function (container, pool) { _super.prototype.init.call(this, container, pool); container._initNode(this); this._hierarchicalPropsDirty = HierarchicalProperty.ALL; this._activeTransform = this._asset.transform; }; ContainerNode.prototype.getLocalNode = function () { if (!this._localNode) { /** * projection is not simple object * not needed spawn it for every cached partition * it has 3 matrices = 100 bytes + Transform, * that have 4 matrices + a lot of vectors (16 bytes) = 300 bytes, * And this is under heavy extending. 1 projection allocate more that 4kb per instance */ var projection = new PerspectiveProjection(); projection.coordinateSystem = CoordinateSystem.LEFT_HANDED; projection.originX = -1; projection.originY = -1; projection.transform = new Transform(); projection.transform.moveTo(0, 0, -1000); projection.transform.lookAt(new Vector3D()); var view = new View(projection, this.view.stage); view.backgroundAlpha = 0; this._localNode = view.getNode(this._asset); this._localNode.transformDisabled = true; this._localNode.setParent(this); } return this._localNode; }; ContainerNode.prototype.clearLocalNode = function () { if (this._localNode) { this._localNode.onClear(null); this._localNode = null; } }; ContainerNode.prototype.onClear = function (event) { this.clearLocalNode(); if (this._pickObject) { this._pickObject = null; this._pickObjectNode.setParent(null); this._pickObjectNode = null; } for (var i = 0; i < this._numChildNodes; i++) this._childNodes[i].onClear(event); this._childNodes.length = 0; this._numChildNodes = 0; this._scrollRect = null; this._scrollRectNode = null; this._renderToImage = false; this._isDragEntity = false; this._positionDirty = false; this._scale9Container = null; this._inverseMatrix3DDirty = true; this._maskDisabled = false; this._colorTransformDisabled = false; this._transformDisabled = false; this._maskOwners = null; this._masks.length = 0; this._parent = null; _super.prototype.clear.call(this); _super.prototype.onClear.call(this, event); }; ContainerNode.prototype.onInvalidate = function (event) { this.invalidate(); }; ContainerNode.prototype.clear = function () { _super.prototype.clear.call(this); if (this._localNode) this._localNode.clear(); for (var i = 0; i < this._numChildNodes; i++) this._childNodes[i].clear(); if (this._pickObject) this._pickObjectNode.clear(); }; ContainerNode.prototype.isInFrustum = function (_rootEntity, _planes, _numPlanes, _pickGroup) { return !this.isInvisible(); }; ContainerNode.prototype.invalidate = function () { if (this._invalid) return; this._invalid = true; _super.prototype.invalidate.call(this); if (this._parent) this._parent.invalidate(); }; /** * @internal */ ContainerNode.prototype.isInvisible = function () { var _a; if (this._hierarchicalPropsDirty & HierarchicalProperty.VISIBLE) { this._invisible = this._transformDisabled ? false : !this._asset.visible || ((_a = this.parent) === null || _a === void 0 ? void 0 : _a.isInvisible()); this._hierarchicalPropsDirty ^= HierarchicalProperty.VISIBLE; } return this._invisible; }; ContainerNode.prototype.isIntersectingRay = function (_rootEntity, _rayPosition, _rayDirection, _pickGroup) { return true; }; /** * * @returns {boolean} */ ContainerNode.prototype.isRenderable = function () { // if container is invisible - all child nodes automatically invisible to return this.getMaskId() != -1 || !this.isInvisible() && this.getColorTransform()._isRenderable(); }; /** * * @returns {boolean} */ ContainerNode.prototype.isCastingShadow = function () { return true; }; /** * @param traverser */ ContainerNode.prototype.acceptTraverser = function (traverser) { this._invalid = false; //get the sub-traverser for the partition, if different, terminate this traversal if (traverser.node != this && traverser !== traverser.getTraverser(this)) return; if (!traverser.enterNode(this)) return; if (!this._asset.maskMode && this._scrollRect !== this._asset.scrollRect) { this._scrollRect = this._asset.scrollRect; if (this._scrollRectNode) { this._scrollRectNode.setParent(null); this._scrollRectNode = null; } if (this._scrollRect) { this._scrollRectNode = this._asset.getScrollRectPrimitive() .getAbstraction(this._pool); this._scrollRectNode.container.scrollRect = this._scrollRect; this._scrollRectNode.setParent(this); } } traverser.applyEntity(this); for (var i = 0; i < this._numChildNodes; i++) this._childNodes[i].acceptTraverser(traverser); }; ContainerNode.prototype.addChildAt = function (entity, index) { var node = entity.getAbstraction(this._pool); node.setParent(this); if (index == this._numChildNodes) this._childNodes.push(node); else this._childNodes.splice(index, 0, node); this._numChildNodes++; this.invalidate(); return node; }; ContainerNode.prototype.removeChildAt = function (index) { this._numChildNodes--; var node = (index === this._numChildNodes) ? this._childNodes.pop() : this._childNodes.splice(index, 1)[0]; node.setParent(null); this.invalidate(); return node; }; ContainerNode.prototype.getChildAt = function (index) { return this._childNodes.length > index ? this._childNodes[index] : null; }; ContainerNode.prototype.startDrag = function () { this._isDragEntity = true; }; ContainerNode.prototype.stopDrag = function () { this._isDragEntity = false; }; ContainerNode.prototype.isDragEntity = function () { return this._isDragEntity; }; ContainerNode.prototype.isMouseDisabled = function () { var _a; return this.isInvisible() || !this._asset.mouseEnabled || ((_a = this.parent) === null || _a === void 0 ? void 0 : _a.isMouseChildrenDisabled()); }; ContainerNode.prototype.isMouseChildrenDisabled = function () { var _a; if (this._hierarchicalPropsDirty & HierarchicalProperty.MOUSE_ENABLED) { this._mouseChildrenDisabled = !this._asset.mouseChildren || ((_a = this.parent) === null || _a === void 0 ? void 0 : _a.isMouseChildrenDisabled()); this._hierarchicalPropsDirty ^= HierarchicalProperty.MOUSE_ENABLED; } return this._mouseChildrenDisabled; }; ContainerNode.prototype.isDescendant = function (node) { var parent = this; while (parent.parent) { parent = parent.parent; if (parent == node) return true; } return false; }; ContainerNode.prototype.invalidateHierarchicalProperty = function (property) { // property dirty check not working for ColorTransform // will emit every change // todo Fixme if (property & HierarchicalProperty.COLOR_TRANSFORM) { // eslint-disable-next-line max-len this.dispatchEvent(this._invalidateColorTransformEvent || (this._invalidateColorTransformEvent = new ContainerNodeEvent(ContainerNodeEvent.INVALIDATE_COLOR_TRANSFORM))); } var propertyDirty = (this._hierarchicalPropsDirty ^ property) & property; if (!propertyDirty) return; this._hierarchicalPropsDirty |= propertyDirty; for (var i = 0; i < this._childNodes.length; ++i) this._childNodes[i].invalidateHierarchicalProperty(property); if (this._pickObjectNode) this._pickObjectNode.invalidateHierarchicalProperty(property); if (this._localNode) this._localNode.invalidateHierarchicalProperty(property); if (property & HierarchicalProperty.SCENE_TRANSFORM) { this._positionDirty = true; this._inverseMatrix3DDirty = true; this.dispatchEvent(this._invalidateMatrix3DEvent || (this._invalidateMatrix3DEvent = new ContainerNodeEvent(ContainerNodeEvent.INVALIDATE_MATRIX3D))); this.invalidate(); } }; ContainerNode.prototype.setParent = function (parent) { if (this._parent) this.clear(); this._parent = parent; this.invalidateHierarchicalProperty(HierarchicalProperty.ALL); }; ContainerNode._nullTransform = new Transform(); ContainerNode._tempVector3D = new Vector3D(); ContainerNode._nullColorTransform = new ColorTransform(); return ContainerNode; }(AbstractionBase)); export { ContainerNode };