@galacean/engine 0.0.0-experimental-2.0-game.6 → 0.0.0-experimental-2.0-game.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/browser.js CHANGED
@@ -7785,7 +7785,7 @@
7785
7785
  var _sprite__getPositions = sprite._getPositions(), lPosLB = _sprite__getPositions[0], lPosRB = _sprite__getPositions[1], lPosLT = _sprite__getPositions[2], lPosRT = _sprite__getPositions[3];
7786
7786
  var spriteUVs = sprite._getUVs();
7787
7787
  var _spriteUVs_ = spriteUVs[0], left = _spriteUVs_.x, bottom = _spriteUVs_.y;
7788
- var _spriteUVs_1 = spriteUVs[3], right = _spriteUVs_1.x, top = _spriteUVs_1.y;
7788
+ var _spriteUVs_1 = spriteUVs[15], right = _spriteUVs_1.x, top = _spriteUVs_1.y;
7789
7789
  var subChunk = renderer._subChunk;
7790
7790
  var vertices = subChunk.chunk.vertices;
7791
7791
  var x0, y0, u0, v0;
@@ -7857,7 +7857,7 @@
7857
7857
  var _sprite__getPositions = sprite._getPositions(), lPosLB = _sprite__getPositions[0], lPosRB = _sprite__getPositions[1], lPosLT = _sprite__getPositions[2], lPosRT = _sprite__getPositions[3];
7858
7858
  var spriteUVs = sprite._getUVs();
7859
7859
  var _spriteUVs_ = spriteUVs[0], left = _spriteUVs_.x, bottom = _spriteUVs_.y;
7860
- var _spriteUVs_1 = spriteUVs[3], right = _spriteUVs_1.x, top = _spriteUVs_1.y;
7860
+ var _spriteUVs_1 = spriteUVs[15], right = _spriteUVs_1.x, top = _spriteUVs_1.y;
7861
7861
  // Transform 4 corners to world space
7862
7862
  var _this__worldPositions = this._worldPositions, wLB = _this__worldPositions[0], wRB = _this__worldPositions[1], wLT = _this__worldPositions[2], wRT = _this__worldPositions[3];
7863
7863
  var _this__uvs = this._uvs, uvLB = _this__uvs[0], uvRB = _this__uvs[1], uvLT = _this__uvs[2], uvRT = _this__uvs[3];
@@ -7909,7 +7909,7 @@
7909
7909
  var _sprite__getPositions = sprite._getPositions(), lPosLB = _sprite__getPositions[0], lPosRB = _sprite__getPositions[1], lPosLT = _sprite__getPositions[2], lPosRT = _sprite__getPositions[3];
7910
7910
  var spriteUVs = sprite._getUVs();
7911
7911
  var _spriteUVs_ = spriteUVs[0], left = _spriteUVs_.x, bottom = _spriteUVs_.y;
7912
- var _spriteUVs_1 = spriteUVs[3], right = _spriteUVs_1.x, top = _spriteUVs_1.y;
7912
+ var _spriteUVs_1 = spriteUVs[15], right = _spriteUVs_1.x, top = _spriteUVs_1.y;
7913
7913
  // Transform corners and compute edge midpoints
7914
7914
  var _this__worldPositions = this._worldPositions, wLB = _this__worldPositions[0], wMB = _this__worldPositions[1], wRB = _this__worldPositions[2], wLM = _this__worldPositions[3], wRM = _this__worldPositions[5], wLT = _this__worldPositions[6], wMT = _this__worldPositions[7], wRT = _this__worldPositions[8];
7915
7915
  var _this__uvs = this._uvs, uvLB = _this__uvs[0], uvMB = _this__uvs[1], uvRB = _this__uvs[2], uvLM = _this__uvs[3], uvRM = _this__uvs[5], uvLT = _this__uvs[6], uvMT = _this__uvs[7], uvRT = _this__uvs[8];
@@ -8010,7 +8010,7 @@
8010
8010
  var _sprite__getPositions = sprite._getPositions(), lPosLB = _sprite__getPositions[0], lPosRB = _sprite__getPositions[1], lPosLT = _sprite__getPositions[2], lPosRT = _sprite__getPositions[3];
8011
8011
  var spriteUVs = sprite._getUVs();
8012
8012
  var _spriteUVs_ = spriteUVs[0], left = _spriteUVs_.x, bottom = _spriteUVs_.y;
8013
- var _spriteUVs_1 = spriteUVs[3], right = _spriteUVs_1.x, top = _spriteUVs_1.y;
8013
+ var _spriteUVs_1 = spriteUVs[15], right = _spriteUVs_1.x, top = _spriteUVs_1.y;
8014
8014
  // ---------------
8015
8015
  // LT - MT - RT
8016
8016
  // | | |
@@ -9606,470 +9606,33 @@
9606
9606
  /** Align bottom vertically */ TextVerticalAlignment[TextVerticalAlignment["Bottom"] = 2] = "Bottom";
9607
9607
  return TextVerticalAlignment;
9608
9608
  }({});
9609
- /**
9610
- * @internal
9611
- */ var UpdateFlagManager = /*#__PURE__*/ function() {
9612
- function UpdateFlagManager() {
9613
- /** @internal */ this._updateFlags = [];
9614
- this._listeners = [];
9609
+ var RenderElement = /*#__PURE__*/ function() {
9610
+ function RenderElement() {
9611
+ this.instancedRenderers = [];
9615
9612
  }
9616
- var _proto = UpdateFlagManager.prototype;
9617
- /**
9618
- * Create a UpdateFlag.
9619
- * @returns - The UpdateFlag.
9620
- */ _proto.createFlag = function createFlag(type) {
9621
- var flag = new type();
9622
- this.addFlag(flag);
9623
- return flag;
9624
- };
9625
- /**
9626
- * Add a UpdateFlag.
9627
- * @param flag - The UpdateFlag.
9628
- */ _proto.addFlag = function addFlag(flag) {
9629
- this._updateFlags.push(flag);
9630
- flag._flagManagers.push(this);
9631
- };
9632
- /**
9633
- * Remove a UpdateFlag.
9634
- * @param flag - The UpdateFlag.
9635
- */ _proto.removeFlag = function removeFlag(flag) {
9636
- var success = Utils.removeFromArray(this._updateFlags, flag);
9637
- if (success) {
9638
- Utils.removeFromArray(flag._flagManagers, this);
9639
- }
9640
- };
9641
- /**
9642
- * Add a listener.
9643
- * @param listener - The listener
9644
- */ _proto.addListener = function addListener(listener) {
9645
- this._listeners.push(listener);
9646
- };
9647
- /**
9648
- * Remove a listener.
9649
- * @param listener - The listener
9650
- */ _proto.removeListener = function removeListener(listener) {
9651
- Utils.removeFromArray(this._listeners, listener);
9613
+ var _proto = RenderElement.prototype;
9614
+ _proto.set = function set(component, material, primitive, subPrimitive, texture, subChunk) {
9615
+ this.component = component;
9616
+ this.material = material;
9617
+ this.primitive = primitive;
9618
+ this.subPrimitive = subPrimitive;
9619
+ this.texture = texture;
9620
+ this.subChunk = subChunk;
9621
+ this.instancedRenderers.length = 0;
9652
9622
  };
9653
- /**
9654
- * Dispatch a event.
9655
- * @param type - Event type, usually in the form of enumeration
9656
- * @param param - Event param
9657
- */ _proto.dispatch = function dispatch(type, param) {
9658
- var updateFlags = this._updateFlags;
9659
- for(var i = updateFlags.length - 1; i >= 0; i--){
9660
- updateFlags[i].dispatch(type, param);
9661
- }
9662
- var listeners = this._listeners;
9663
- for(var i1 = listeners.length - 1; i1 >= 0; i1--){
9664
- listeners[i1](type, param);
9665
- }
9623
+ _proto.dispose = function dispose() {
9624
+ this.component = null;
9625
+ this.material = null;
9626
+ this.primitive = null;
9627
+ this.subPrimitive = null;
9628
+ this.subShader = null;
9629
+ this.shaderData && (this.shaderData = null);
9630
+ this.instancedRenderers = null;
9631
+ this.texture && (this.texture = null);
9632
+ this.subChunk && (this.subChunk = null);
9666
9633
  };
9667
- return UpdateFlagManager;
9634
+ return RenderElement;
9668
9635
  }();
9669
- /**
9670
- * 2D sprite.
9671
- */ var Sprite = /*#__PURE__*/ function(ReferResource) {
9672
- _inherits$2(Sprite, ReferResource);
9673
- function Sprite(engine, texture, region, pivot, border, name) {
9674
- if (texture === void 0) texture = null;
9675
- if (region === void 0) region = null;
9676
- if (pivot === void 0) pivot = null;
9677
- if (border === void 0) border = null;
9678
- if (name === void 0) name = null;
9679
- var _this;
9680
- _this = ReferResource.call(this, engine) || this, _this._automaticWidth = 0, _this._automaticHeight = 0, _this._customWidth = undefined, _this._customHeight = undefined, _this._positions = [
9681
- new Vector2(),
9682
- new Vector2(),
9683
- new Vector2(),
9684
- new Vector2()
9685
- ], // 与 SlicedAssembler/TiledAssembler 的 vertex 索引图一致:[0]=LB, [3]=LT, [12]=RB, [15]=RT。
9686
- // SimpleAssembler 取 [0]/[3]/[12]/[15] 4 个 corner;Sliced/Tiled 用全 16。
9687
- // prettier-ignore
9688
- _this._uvs = [
9689
- new Vector2(),
9690
- new Vector2(),
9691
- new Vector2(),
9692
- new Vector2(),
9693
- new Vector2(),
9694
- new Vector2(),
9695
- new Vector2(),
9696
- new Vector2(),
9697
- new Vector2(),
9698
- new Vector2(),
9699
- new Vector2(),
9700
- new Vector2(),
9701
- new Vector2(),
9702
- new Vector2(),
9703
- new Vector2(),
9704
- new Vector2()
9705
- ], _this._bounds = new BoundingBox(), _this._texture = null, _this._atlasRotated = false, _this._atlasRegion = new Rect(0, 0, 1, 1), _this._atlasRegionOffset = new Vector4(0, 0, 0, 0), _this._region = new Rect(0, 0, 1, 1), _this._pivot = new Vector2(0.5, 0.5), _this._border = new Vector4(0, 0, 0, 0), _this._dirtyUpdateFlag = 7, /** @internal */ _this._updateFlagManager = new UpdateFlagManager();
9706
- _this._texture = texture;
9707
- _this._onRegionChange = _this._onRegionChange.bind(_this);
9708
- _this._onPivotChange = _this._onPivotChange.bind(_this);
9709
- _this._onBorderChange = _this._onBorderChange.bind(_this);
9710
- // @ts-ignore
9711
- _this._region._onValueChanged = _this._onRegionChange;
9712
- // @ts-ignore
9713
- _this._pivot._onValueChanged = _this._onPivotChange;
9714
- // @ts-ignore
9715
- _this._border._onValueChanged = _this._onBorderChange;
9716
- region && _this._region.copyFrom(region);
9717
- pivot && _this._pivot.copyFrom(pivot);
9718
- border && _this._border.copyFrom(border);
9719
- _this.name = name;
9720
- return _this;
9721
- }
9722
- var _proto = Sprite.prototype;
9723
- /**
9724
- * Clone.
9725
- * @returns Cloned sprite
9726
- */ _proto.clone = function clone() {
9727
- var cloneSprite = new Sprite(this._engine, this._texture, this._region, this._pivot, this._border, this.name);
9728
- cloneSprite._atlasRotated = this._atlasRotated;
9729
- cloneSprite._atlasRegion.copyFrom(this._atlasRegion);
9730
- cloneSprite._atlasRegionOffset.copyFrom(this._atlasRegionOffset);
9731
- return cloneSprite;
9732
- };
9733
- /**
9734
- * @internal
9735
- */ _proto._getPositions = function _getPositions() {
9736
- this._dirtyUpdateFlag & 1 && this._updatePositions();
9737
- return this._positions;
9738
- };
9739
- /**
9740
- * @internal
9741
- */ _proto._getUVs = function _getUVs() {
9742
- this._dirtyUpdateFlag & 2 && this._updateUVs();
9743
- return this._uvs;
9744
- };
9745
- /**
9746
- * @internal
9747
- */ _proto._getBounds = function _getBounds() {
9748
- this._dirtyUpdateFlag & 1 && this._updatePositions();
9749
- return this._bounds;
9750
- };
9751
- /**
9752
- * @internal
9753
- */ _proto._addReferCount = function _addReferCount(value) {
9754
- var _this__atlas;
9755
- ReferResource.prototype._addReferCount.call(this, value);
9756
- (_this__atlas = this._atlas) == null ? void 0 : _this__atlas._addReferCount(value);
9757
- };
9758
- /**
9759
- * @internal
9760
- */ _proto._onDestroy = function _onDestroy() {
9761
- this._dispatchSpriteChange(SpriteModifyFlags.destroy);
9762
- ReferResource.prototype._onDestroy.call(this);
9763
- this._positions.length = 0;
9764
- this._positions = null;
9765
- this._uvs.length = 0;
9766
- this._uvs = null;
9767
- this._atlasRegion = null;
9768
- this._atlasRegionOffset = null;
9769
- this._region = null;
9770
- this._pivot = null;
9771
- this._border = null;
9772
- this._bounds = null;
9773
- this._atlas = null;
9774
- this._texture = null;
9775
- };
9776
- _proto._calDefaultSize = function _calDefaultSize() {
9777
- if (this._texture) {
9778
- var _this = this, _texture = _this._texture, _atlasRegion = _this._atlasRegion, _atlasRegionOffset = _this._atlasRegionOffset, _region = _this._region, _atlasRotated = _this._atlasRotated;
9779
- var ppuReciprocal = 1.0 / Engine._pixelsPerUnit;
9780
- // 先算 atlas 中绝对像素(texture 不一定是方形,必须各自乘对应维度)
9781
- var atlasPxW = _texture.width * _atlasRegion.width;
9782
- var atlasPxH = _texture.height * _atlasRegion.height;
9783
- // atlas 顺时针 pack 90°:原图 W×H 在 atlas 中占 H×W 区域,仅交换 atlasPx 的 W/H
9784
- var originWidth = _atlasRotated ? atlasPxH : atlasPxW;
9785
- var originHeight = _atlasRotated ? atlasPxW : atlasPxH;
9786
- this._automaticWidth = originWidth / (1 - _atlasRegionOffset.x - _atlasRegionOffset.z) * _region.width * ppuReciprocal;
9787
- this._automaticHeight = originHeight / (1 - _atlasRegionOffset.y - _atlasRegionOffset.w) * _region.height * ppuReciprocal;
9788
- } else {
9789
- this._automaticWidth = this._automaticHeight = 0;
9790
- }
9791
- this._dirtyUpdateFlag &= ~4;
9792
- };
9793
- _proto._updatePositions = function _updatePositions() {
9794
- var blank = this._atlasRegionOffset;
9795
- var _this__region = this._region, regionX = _this__region.x, regionY = _this__region.y, regionW = _this__region.width, regionH = _this__region.height;
9796
- var regionRight = 1 - regionX - regionW;
9797
- var regionBottom = 1 - regionY - regionH;
9798
- var left = Math.max(blank.x - regionX, 0) / regionW;
9799
- var bottom = Math.max(blank.w - regionY, 0) / regionH;
9800
- var right = 1 - Math.max(blank.z - regionRight, 0) / regionW;
9801
- var top = 1 - Math.max(blank.y - regionBottom, 0) / regionH;
9802
- // Update positions.
9803
- // ---------------
9804
- // 2 - 3
9805
- // | |
9806
- // 0 - 1
9807
- // ---------------
9808
- var positions = this._positions;
9809
- positions[0].set(left, bottom);
9810
- positions[1].set(right, bottom);
9811
- positions[2].set(left, top);
9812
- positions[3].set(right, top);
9813
- var bounds = this._bounds;
9814
- bounds.min.set(left, bottom, 0);
9815
- bounds.max.set(right, top, 0);
9816
- this._dirtyUpdateFlag &= ~1;
9817
- };
9818
- _proto._updateUVs = function _updateUVs() {
9819
- var _this = this, uvs = _this._uvs, atlasRotated = _this._atlasRotated, border = _this._border;
9820
- var _this__region = this._region, regionLeft = _this__region.x, regionTop = _this__region.y, regionW = _this__region.width, regionH = _this__region.height;
9821
- var regionRight = 1 - regionLeft - regionW;
9822
- var regionBottom = 1 - regionTop - regionH;
9823
- var _this__atlasRegion = this._atlasRegion, atlasRegionX = _this__atlasRegion.x, atlasRegionY = _this__atlasRegion.y, atlasRegionW = _this__atlasRegion.width, atlasRegionH = _this__atlasRegion.height;
9824
- var _this__atlasRegionOffset = this._atlasRegionOffset, offsetLeft = _this__atlasRegionOffset.x, offsetTop = _this__atlasRegionOffset.y, offsetRight = _this__atlasRegionOffset.z, offsetBottom = _this__atlasRegionOffset.w;
9825
- var realWidth = atlasRegionW / (1 - offsetLeft - offsetRight);
9826
- var realHeight = atlasRegionH / (1 - offsetTop - offsetBottom);
9827
- // 4 个外边界 + 4 个 9-slice 内边界
9828
- var left, top, right, bottom;
9829
- var bLeft, bTop, bRight, bBottom;
9830
- if (atlasRotated) {
9831
- // 原图 region/offset (left/top/right/bottom) 在 atlas 中映射为 (bottom/left/top/right)
9832
- left = Math.max(regionBottom - offsetLeft, 0) * realWidth + atlasRegionX;
9833
- top = Math.max(regionLeft - offsetTop, 0) * realHeight + atlasRegionY;
9834
- right = atlasRegionW + atlasRegionX - Math.max(regionTop - offsetRight, 0) * realWidth;
9835
- bottom = atlasRegionH + atlasRegionY - Math.max(regionRight - offsetBottom, 0) * realHeight;
9836
- bLeft = (regionBottom - offsetLeft + border.y * regionH) * realWidth + atlasRegionX;
9837
- bTop = (regionLeft - offsetTop + border.x * regionW) * realHeight + atlasRegionY;
9838
- bRight = atlasRegionW + atlasRegionX - (regionTop - offsetRight + border.w * regionH) * realWidth;
9839
- bBottom = atlasRegionH + atlasRegionY - (regionRight - offsetBottom + border.z * regionW) * realHeight;
9840
- } else {
9841
- left = Math.max(regionLeft - offsetLeft, 0) * realWidth + atlasRegionX;
9842
- top = Math.max(regionBottom - offsetTop, 0) * realHeight + atlasRegionY;
9843
- right = atlasRegionW + atlasRegionX - Math.max(regionRight - offsetRight, 0) * realWidth;
9844
- bottom = atlasRegionH + atlasRegionY - Math.max(regionTop - offsetBottom, 0) * realHeight;
9845
- bLeft = (regionLeft - offsetLeft + border.x * regionW) * realWidth + atlasRegionX;
9846
- bTop = (regionBottom - offsetTop + border.w * regionH) * realHeight + atlasRegionY;
9847
- bRight = atlasRegionW + atlasRegionX - (regionRight - offsetRight + border.z * regionW) * realWidth;
9848
- bBottom = atlasRegionH + atlasRegionY - (regionTop - offsetBottom + border.y * regionH) * realHeight;
9849
- }
9850
- // 16 UV 网格填充(column-major:index=i*4+j,i=column[0=left..3=right],j=row[0=bottom..3=top])
9851
- // - 非 rotated:column 决定 atlas X (left/bLeft/bRight/right),row 决定 atlas Y (bottom/bBottom/bTop/top)
9852
- // - rotated 90° 顺时针 packed:display column 对应 atlas Y 的反向(顶→底),display row 对应 atlas X
9853
- if (atlasRotated) {
9854
- uvs[0].set(left, top), uvs[1].set(bLeft, top), uvs[2].set(bRight, top), uvs[3].set(right, top);
9855
- uvs[4].set(left, bTop), uvs[5].set(bLeft, bTop), uvs[6].set(bRight, bTop), uvs[7].set(right, bTop);
9856
- uvs[8].set(left, bBottom), uvs[9].set(bLeft, bBottom), uvs[10].set(bRight, bBottom), uvs[11].set(right, bBottom);
9857
- uvs[12].set(left, bottom), uvs[13].set(bLeft, bottom), uvs[14].set(bRight, bottom), uvs[15].set(right, bottom);
9858
- } else {
9859
- uvs[0].set(left, bottom), uvs[1].set(left, bBottom), uvs[2].set(left, bTop), uvs[3].set(left, top);
9860
- uvs[4].set(bLeft, bottom), uvs[5].set(bLeft, bBottom), uvs[6].set(bLeft, bTop), uvs[7].set(bLeft, top);
9861
- uvs[8].set(bRight, bottom), uvs[9].set(bRight, bBottom), uvs[10].set(bRight, bTop), uvs[11].set(bRight, top);
9862
- uvs[12].set(right, bottom), uvs[13].set(right, bBottom), uvs[14].set(right, bTop), uvs[15].set(right, top);
9863
- }
9864
- this._dirtyUpdateFlag &= ~2;
9865
- };
9866
- _proto._dispatchSpriteChange = function _dispatchSpriteChange(type) {
9867
- switch(type){
9868
- case SpriteModifyFlags.texture:
9869
- this._dirtyUpdateFlag |= 4;
9870
- break;
9871
- case SpriteModifyFlags.atlasRegionOffset:
9872
- case SpriteModifyFlags.region:
9873
- this._dirtyUpdateFlag |= 7;
9874
- break;
9875
- case SpriteModifyFlags.atlasRegion:
9876
- this._dirtyUpdateFlag |= 4 | 2;
9877
- break;
9878
- case SpriteModifyFlags.border:
9879
- this._dirtyUpdateFlag |= 2;
9880
- break;
9881
- }
9882
- this._updateFlagManager.dispatch(type);
9883
- };
9884
- _proto._onRegionChange = function _onRegionChange() {
9885
- var _this = this, region = _this._region;
9886
- // @ts-ignore
9887
- region._onValueChanged = null;
9888
- var x = MathUtil.clamp(region.x, 0, 1);
9889
- var y = MathUtil.clamp(region.y, 0, 1);
9890
- region.set(x, y, MathUtil.clamp(region.width, 0, 1 - x), MathUtil.clamp(region.height, 0, 1 - y));
9891
- this._dispatchSpriteChange(SpriteModifyFlags.region);
9892
- if (this._customWidth === undefined || this._customHeight === undefined) {
9893
- this._dispatchSpriteChange(SpriteModifyFlags.size);
9894
- }
9895
- // @ts-ignore
9896
- region._onValueChanged = this._onRegionChange;
9897
- };
9898
- _proto._onPivotChange = function _onPivotChange() {
9899
- this._dispatchSpriteChange(SpriteModifyFlags.pivot);
9900
- };
9901
- _proto._onBorderChange = function _onBorderChange() {
9902
- var _this = this, border = _this._border;
9903
- // @ts-ignore
9904
- border._onValueChanged = null;
9905
- var x = MathUtil.clamp(border.x, 0, 1);
9906
- var y = MathUtil.clamp(border.y, 0, 1);
9907
- border.set(x, y, MathUtil.clamp(border.z, 0, 1 - x), MathUtil.clamp(border.w, 0, 1 - y));
9908
- this._dispatchSpriteChange(SpriteModifyFlags.border);
9909
- // @ts-ignore
9910
- border._onValueChanged = this._onBorderChange;
9911
- };
9912
- _create_class$2(Sprite, [
9913
- {
9914
- key: "texture",
9915
- get: /**
9916
- * The reference to the used texture.
9917
- */ function get() {
9918
- return this._texture;
9919
- },
9920
- set: function set(value) {
9921
- if (this._texture !== value) {
9922
- this._texture = value;
9923
- this._dispatchSpriteChange(SpriteModifyFlags.texture);
9924
- if (this._customWidth === undefined || this._customHeight === undefined) {
9925
- this._dispatchSpriteChange(SpriteModifyFlags.size);
9926
- }
9927
- }
9928
- }
9929
- },
9930
- {
9931
- key: "width",
9932
- get: /**
9933
- * The width of the sprite (in world coordinates).
9934
- *
9935
- * @remarks
9936
- * If width is set, return the set value,
9937
- * otherwise return the width calculated according to `Texture.width`, `Sprite.region`, `Sprite.atlasRegion` and `Sprite.atlasRegionOffset`.
9938
- */ function get() {
9939
- if (this._customWidth !== undefined) {
9940
- return this._customWidth;
9941
- } else {
9942
- this._dirtyUpdateFlag & 4 && this._calDefaultSize();
9943
- return this._automaticWidth;
9944
- }
9945
- },
9946
- set: function set(value) {
9947
- if (this._customWidth !== value) {
9948
- this._customWidth = value;
9949
- this._dispatchSpriteChange(SpriteModifyFlags.size);
9950
- }
9951
- }
9952
- },
9953
- {
9954
- key: "height",
9955
- get: /**
9956
- * The height of the sprite (in world coordinates).
9957
- *
9958
- * @remarks
9959
- * If height is set, return the set value,
9960
- * otherwise return the height calculated according to `Texture.height`, `Sprite.region`, `Sprite.atlasRegion` and `Sprite.atlasRegionOffset`.
9961
- */ function get() {
9962
- if (this._customHeight !== undefined) {
9963
- return this._customHeight;
9964
- } else {
9965
- this._dirtyUpdateFlag & 4 && this._calDefaultSize();
9966
- return this._automaticHeight;
9967
- }
9968
- },
9969
- set: function set(value) {
9970
- if (this._customHeight !== value) {
9971
- this._customHeight = value;
9972
- this._dispatchSpriteChange(SpriteModifyFlags.size);
9973
- }
9974
- }
9975
- },
9976
- {
9977
- key: "atlasRotated",
9978
- get: /**
9979
- * Is it rotated 90 degrees clockwise when packing.
9980
- */ function get() {
9981
- return this._atlasRotated;
9982
- },
9983
- set: function set(value) {
9984
- if (this._atlasRotated != value) {
9985
- this._atlasRotated = value;
9986
- }
9987
- }
9988
- },
9989
- {
9990
- key: "atlasRegion",
9991
- get: /**
9992
- * The rectangle region of the original texture on its atlas texture, specified in normalized.
9993
- */ function get() {
9994
- return this._atlasRegion;
9995
- },
9996
- set: function set(value) {
9997
- var x = MathUtil.clamp(value.x, 0, 1);
9998
- var y = MathUtil.clamp(value.y, 0, 1);
9999
- this._atlasRegion.set(x, y, MathUtil.clamp(value.width, 0, 1 - x), MathUtil.clamp(value.height, 0, 1 - y));
10000
- this._dispatchSpriteChange(SpriteModifyFlags.atlasRegion);
10001
- if (this._customWidth === undefined || this._customHeight === undefined) {
10002
- this._dispatchSpriteChange(SpriteModifyFlags.size);
10003
- }
10004
- }
10005
- },
10006
- {
10007
- key: "atlasRegionOffset",
10008
- get: /**
10009
- * The rectangle region offset of the original texture on its atlas texture, specified in normalized.
10010
- */ function get() {
10011
- return this._atlasRegionOffset;
10012
- },
10013
- set: function set(value) {
10014
- var x = MathUtil.clamp(value.x, 0, 1);
10015
- var y = MathUtil.clamp(value.y, 0, 1);
10016
- this._atlasRegionOffset.set(x, y, MathUtil.clamp(value.z, 0, 1 - x), MathUtil.clamp(value.w, 0, 1 - y));
10017
- this._dispatchSpriteChange(SpriteModifyFlags.atlasRegionOffset);
10018
- if (this._customWidth === undefined || this._customHeight === undefined) {
10019
- this._dispatchSpriteChange(SpriteModifyFlags.size);
10020
- }
10021
- }
10022
- },
10023
- {
10024
- key: "region",
10025
- get: /**
10026
- * The rectangle region of the sprite, specified in normalized.
10027
- */ function get() {
10028
- return this._region;
10029
- },
10030
- set: function set(value) {
10031
- this._region !== value && this._region.copyFrom(value);
10032
- }
10033
- },
10034
- {
10035
- key: "pivot",
10036
- get: /**
10037
- * Location of the sprite's center point in the rectangle region, specified in normalized.
10038
- * The origin is at the bottom left and the default value is (0.5, 0.5).
10039
- */ function get() {
10040
- return this._pivot;
10041
- },
10042
- set: function set(value) {
10043
- this._pivot !== value && this._pivot.copyFrom(value);
10044
- }
10045
- },
10046
- {
10047
- key: "border",
10048
- get: /**
10049
- * Get the border of the sprite.
10050
- * x y z w
10051
- * | | | |
10052
- * Left, bottom, right, top.
10053
- * @remarks only use in sliced mode.
10054
- */ function get() {
10055
- return this._border;
10056
- },
10057
- set: function set(value) {
10058
- this._border !== value && this._border.copyFrom(value);
10059
- }
10060
- }
10061
- ]);
10062
- return Sprite;
10063
- }(ReferResource);
10064
- __decorate$1([
10065
- ignoreClone
10066
- ], Sprite.prototype, "_onRegionChange", null);
10067
- __decorate$1([
10068
- ignoreClone
10069
- ], Sprite.prototype, "_onPivotChange", null);
10070
- __decorate$1([
10071
- ignoreClone
10072
- ], Sprite.prototype, "_onBorderChange", null);
10073
9636
  /**
10074
9637
  * Blend factor.
10075
9638
  * @remarks defines which function is used for blending pixel arithmetic
@@ -10451,6 +10014,66 @@
10451
10014
  };
10452
10015
  return _extends$2.apply(this, arguments);
10453
10016
  }
10017
+ /**
10018
+ * @internal
10019
+ */ var UpdateFlagManager = /*#__PURE__*/ function() {
10020
+ function UpdateFlagManager() {
10021
+ /** @internal */ this._updateFlags = [];
10022
+ this._listeners = [];
10023
+ }
10024
+ var _proto = UpdateFlagManager.prototype;
10025
+ /**
10026
+ * Create a UpdateFlag.
10027
+ * @returns - The UpdateFlag.
10028
+ */ _proto.createFlag = function createFlag(type) {
10029
+ var flag = new type();
10030
+ this.addFlag(flag);
10031
+ return flag;
10032
+ };
10033
+ /**
10034
+ * Add a UpdateFlag.
10035
+ * @param flag - The UpdateFlag.
10036
+ */ _proto.addFlag = function addFlag(flag) {
10037
+ this._updateFlags.push(flag);
10038
+ flag._flagManagers.push(this);
10039
+ };
10040
+ /**
10041
+ * Remove a UpdateFlag.
10042
+ * @param flag - The UpdateFlag.
10043
+ */ _proto.removeFlag = function removeFlag(flag) {
10044
+ var success = Utils.removeFromArray(this._updateFlags, flag);
10045
+ if (success) {
10046
+ Utils.removeFromArray(flag._flagManagers, this);
10047
+ }
10048
+ };
10049
+ /**
10050
+ * Add a listener.
10051
+ * @param listener - The listener
10052
+ */ _proto.addListener = function addListener(listener) {
10053
+ this._listeners.push(listener);
10054
+ };
10055
+ /**
10056
+ * Remove a listener.
10057
+ * @param listener - The listener
10058
+ */ _proto.removeListener = function removeListener(listener) {
10059
+ Utils.removeFromArray(this._listeners, listener);
10060
+ };
10061
+ /**
10062
+ * Dispatch a event.
10063
+ * @param type - Event type, usually in the form of enumeration
10064
+ * @param param - Event param
10065
+ */ _proto.dispatch = function dispatch(type, param) {
10066
+ var updateFlags = this._updateFlags;
10067
+ for(var i = updateFlags.length - 1; i >= 0; i--){
10068
+ updateFlags[i].dispatch(type, param);
10069
+ }
10070
+ var listeners = this._listeners;
10071
+ for(var i1 = listeners.length - 1; i1 >= 0; i1--){
10072
+ listeners[i1](type, param);
10073
+ }
10074
+ };
10075
+ return UpdateFlagManager;
10076
+ }();
10454
10077
  /**
10455
10078
  * Buffer usage.
10456
10079
  */ var BufferUsage = /*#__PURE__*/ function(BufferUsage) {
@@ -12118,7 +11741,7 @@
12118
11741
  _inherits$2(Renderer, Component);
12119
11742
  function Renderer(entity) {
12120
11743
  var _this;
12121
- _this = Component.call(this, entity) || this, /** @internal */ _this._onUpdateIndex = -1, /** @internal */ _this._rendererIndex = -1, /** @internal */ _this._globalShaderMacro = new ShaderMacroCollection(), /** @internal */ _this._maskInteraction = SpriteMaskInteraction.None, _this._maskLayer = SpriteMaskLayer.Layer0, _this._overrideUpdate = false, _this._materials = [], _this._dirtyUpdateFlag = 0, _this._rendererLayer = new Vector4(), _this._bounds = new BoundingBox(), _this._shaderData = new ShaderData(ShaderDataGroup.Renderer), _this._mvMatrix = new Matrix(), _this._mvpMatrix = new Matrix(), _this._normalMatrix = new Matrix(), _this._materialsInstanced = [], _this._priority = 0, _this._receiveShadows = true, /** Whether cast shadow. */ _this.castShadows = true;
11744
+ _this = Component.call(this, entity) || this, /** @internal */ _this._onUpdateIndex = -1, /** @internal */ _this._rendererIndex = -1, /** @internal */ _this._globalShaderMacro = new ShaderMacroCollection(), _this._maskInteraction = SpriteMaskInteraction.None, _this._maskLayer = SpriteMaskLayer.Layer0, _this._overrideUpdate = false, _this._materials = [], _this._dirtyUpdateFlag = 0, _this._rendererLayer = new Vector4(), _this._bounds = new BoundingBox(), _this._shaderData = new ShaderData(ShaderDataGroup.Renderer), _this._mvMatrix = new Matrix(), _this._mvpMatrix = new Matrix(), _this._normalMatrix = new Matrix(), _this._materialsInstanced = [], _this._priority = 0, _this._receiveShadows = true, /** Whether cast shadow. */ _this.castShadows = true;
12122
11745
  var prototype = Renderer.prototype;
12123
11746
  var shaderData = _this.shaderData;
12124
11747
  _this._overrideUpdate = _this.update !== prototype.update;
@@ -14970,6 +14593,21 @@
14970
14593
  var preRenderer = preElement.component;
14971
14594
  var renderer = curElement.component;
14972
14595
  var maskInteraction = preRenderer.maskInteraction;
14596
+ var preRendererAny = preRenderer;
14597
+ var curRendererAny = renderer;
14598
+ var rectMaskEnabledA = preRendererAny._rectMaskEnabled;
14599
+ if (rectMaskEnabledA !== curRendererAny._rectMaskEnabled) {
14600
+ return false;
14601
+ }
14602
+ if (rectMaskEnabledA) {
14603
+ var rectMaskRectA = preRendererAny._rectMaskRect;
14604
+ var rectMaskRectB = curRendererAny._rectMaskRect;
14605
+ var rectMaskSoftnessA = preRendererAny._rectMaskSoftness;
14606
+ var rectMaskSoftnessB = curRendererAny._rectMaskSoftness;
14607
+ if (!rectMaskRectA || !rectMaskRectB || !rectMaskSoftnessA || !rectMaskSoftnessB || rectMaskRectA.x !== rectMaskRectB.x || rectMaskRectA.y !== rectMaskRectB.y || rectMaskRectA.z !== rectMaskRectB.z || rectMaskRectA.w !== rectMaskRectB.w || rectMaskSoftnessA.x !== rectMaskSoftnessB.x || rectMaskSoftnessA.y !== rectMaskSoftnessB.y || rectMaskSoftnessA.z !== rectMaskSoftnessB.z || rectMaskSoftnessA.w !== rectMaskSoftnessB.w || preRendererAny._rectMaskHardClip !== curRendererAny._rectMaskHardClip) {
14608
+ return false;
14609
+ }
14610
+ }
14973
14611
  // Order: cheap reference checks → mask state → tag lookup (rare opt-out)
14974
14612
  return preElement.subChunk.chunk === curElement.subChunk.chunk && preElement.texture === curElement.texture && preElement.material === curElement.material && maskInteraction === renderer.maskInteraction && (maskInteraction === SpriteMaskInteraction.None || preRenderer.maskLayer === renderer.maskLayer) && curElement.subShader.passes[0].getTagValue(VertexMergeBatcher._disableBatchTag) !== true;
14975
14613
  };
@@ -15007,191 +14645,703 @@
15007
14645
  return VertexMergeBatcher;
15008
14646
  }();
15009
14647
  VertexMergeBatcher._disableBatchTag = ShaderTagKey.getByName("spriteDisableBatching");
15010
- var RenderElement = /*#__PURE__*/ function() {
15011
- function RenderElement() {
15012
- this.instancedRenderers = [];
15013
- }
15014
- var _proto = RenderElement.prototype;
15015
- _proto.set = function set(component, material, primitive, subPrimitive, texture, subChunk) {
15016
- this.component = component;
15017
- this.material = material;
15018
- this.primitive = primitive;
15019
- this.subPrimitive = subPrimitive;
15020
- this.texture = texture;
15021
- this.subChunk = subChunk;
15022
- this.instancedRenderers.length = 0;
14648
+ /**
14649
+ * Internal helpers for sprite mask hit testing.
14650
+ * @internal
14651
+ */ var SpriteMaskUtils = /*#__PURE__*/ function() {
14652
+ function SpriteMaskUtils() {}
14653
+ SpriteMaskUtils.containsWorldPoint = function containsWorldPoint(worldPoint, sprite, worldMatrix, width, height, pivot, flipX, flipY, alphaCutoff) {
14654
+ if (alphaCutoff === void 0) alphaCutoff = 0;
14655
+ if (!sprite || !width || !height) {
14656
+ return false;
14657
+ }
14658
+ var worldMatrixInv = SpriteMaskUtils._tempMat;
14659
+ Matrix.invert(worldMatrix, worldMatrixInv);
14660
+ var localPosition = SpriteMaskUtils._tempVec3;
14661
+ Vector3.transformCoordinate(worldPoint, worldMatrixInv, localPosition);
14662
+ var sx = flipX ? -width : width;
14663
+ var sy = flipY ? -height : height;
14664
+ if (!sx || !sy) {
14665
+ return false;
14666
+ }
14667
+ var spriteX = localPosition.x / sx + pivot.x;
14668
+ var spriteY = localPosition.y / sy + pivot.y;
14669
+ var spritePositions = sprite._getPositions();
14670
+ var _spritePositions_ = spritePositions[0], left = _spritePositions_.x, bottom = _spritePositions_.y;
14671
+ var _spritePositions_1 = spritePositions[3], right = _spritePositions_1.x, top = _spritePositions_1.y;
14672
+ if (!(spriteX >= left && spriteX <= right && spriteY >= bottom && spriteY <= top)) {
14673
+ return false;
14674
+ }
14675
+ if (alphaCutoff <= 0) {
14676
+ return true;
14677
+ }
14678
+ var texture = sprite.texture;
14679
+ if (!texture) {
14680
+ return false;
14681
+ }
14682
+ var spriteUVs = sprite._getUVs();
14683
+ var leftU = spriteUVs[0].x;
14684
+ var bottomV = spriteUVs[0].y;
14685
+ var rightU = spriteUVs[3].x;
14686
+ var topV = spriteUVs[3].y;
14687
+ var positionWidth = right - left;
14688
+ var positionHeight = top - bottom;
14689
+ if (!positionWidth || !positionHeight) {
14690
+ return false;
14691
+ }
14692
+ var tx = (spriteX - left) / positionWidth;
14693
+ var ty = (spriteY - bottom) / positionHeight;
14694
+ var u = leftU + (rightU - leftU) * tx;
14695
+ var v = bottomV + (topV - bottomV) * ty;
14696
+ var x = Math.min(Math.max(Math.floor(u * texture.width), 0), texture.width - 1);
14697
+ var y = Math.min(Math.max(Math.floor(v * texture.height), 0), texture.height - 1);
14698
+ return SpriteMaskUtils._sampleTextureAlpha(texture, x, y) >= alphaCutoff;
15023
14699
  };
15024
- _proto.dispose = function dispose() {
15025
- this.component = null;
15026
- this.material = null;
15027
- this.primitive = null;
15028
- this.subPrimitive = null;
15029
- this.subShader = null;
15030
- this.shaderData && (this.shaderData = null);
15031
- this.instancedRenderers = null;
15032
- this.texture && (this.texture = null);
15033
- this.subChunk && (this.subChunk = null);
14700
+ SpriteMaskUtils._sampleTextureAlpha = function _sampleTextureAlpha(texture, x, y) {
14701
+ try {
14702
+ switch(texture.format){
14703
+ case TextureFormat.R8G8B8A8:
14704
+ {
14705
+ var buffer = SpriteMaskUtils._u8Buffer4;
14706
+ texture.getPixelBuffer(x, y, 1, 1, buffer);
14707
+ return buffer[3] / 255;
14708
+ }
14709
+ case TextureFormat.R4G4B4A4:
14710
+ {
14711
+ var buffer1 = SpriteMaskUtils._u16Buffer1;
14712
+ texture.getPixelBuffer(x, y, 1, 1, buffer1);
14713
+ return (buffer1[0] & 0xf) / 15;
14714
+ }
14715
+ case TextureFormat.R5G5B5A1:
14716
+ {
14717
+ var buffer2 = SpriteMaskUtils._u16Buffer1;
14718
+ texture.getPixelBuffer(x, y, 1, 1, buffer2);
14719
+ return buffer2[0] & 0x1;
14720
+ }
14721
+ case TextureFormat.Alpha8:
14722
+ case TextureFormat.R8:
14723
+ {
14724
+ var buffer3 = SpriteMaskUtils._u8Buffer1;
14725
+ texture.getPixelBuffer(x, y, 1, 1, buffer3);
14726
+ return buffer3[0] / 255;
14727
+ }
14728
+ case TextureFormat.LuminanceAlpha:
14729
+ case TextureFormat.R8G8:
14730
+ {
14731
+ var buffer4 = SpriteMaskUtils._u8Buffer2;
14732
+ texture.getPixelBuffer(x, y, 1, 1, buffer4);
14733
+ return buffer4[1] / 255;
14734
+ }
14735
+ case TextureFormat.R16G16B16A16:
14736
+ {
14737
+ var buffer5 = SpriteMaskUtils._u16Buffer4;
14738
+ texture.getPixelBuffer(x, y, 1, 1, buffer5);
14739
+ return buffer5[3] / 65535;
14740
+ }
14741
+ case TextureFormat.R32G32B32A32:
14742
+ {
14743
+ var buffer6 = SpriteMaskUtils._f32Buffer4;
14744
+ texture.getPixelBuffer(x, y, 1, 1, buffer6);
14745
+ return buffer6[3];
14746
+ }
14747
+ case TextureFormat.R32G32B32A32_UInt:
14748
+ {
14749
+ var buffer7 = SpriteMaskUtils._u32Buffer4;
14750
+ texture.getPixelBuffer(x, y, 1, 1, buffer7);
14751
+ return buffer7[3] / 4294967295;
14752
+ }
14753
+ default:
14754
+ return 1;
14755
+ }
14756
+ } catch (e) {
14757
+ return 1;
14758
+ }
15034
14759
  };
15035
- return RenderElement;
14760
+ return SpriteMaskUtils;
15036
14761
  }();
14762
+ SpriteMaskUtils._tempMat = new Matrix();
14763
+ SpriteMaskUtils._tempVec3 = new Vector3();
14764
+ SpriteMaskUtils._u8Buffer1 = new Uint8Array(1);
14765
+ SpriteMaskUtils._u8Buffer2 = new Uint8Array(2);
14766
+ SpriteMaskUtils._u8Buffer4 = new Uint8Array(4);
14767
+ SpriteMaskUtils._u16Buffer1 = new Uint16Array(1);
14768
+ SpriteMaskUtils._u16Buffer4 = new Uint16Array(4);
14769
+ SpriteMaskUtils._f32Buffer4 = new Float32Array(4);
14770
+ SpriteMaskUtils._u32Buffer4 = new Uint32Array(4);
14771
+ /**
14772
+ * Mixin that provides shared mask rendering logic for both 2D SpriteMask and UI Mask.
14773
+ */ function MaskRenderable(Base) {
14774
+ var MaskRenderableBase = /*#__PURE__*/ function(Base) {
14775
+ _inherits$2(MaskRenderableBase, Base);
14776
+ function MaskRenderableBase() {
14777
+ var _this;
14778
+ _this = Base.apply(this, arguments) || this, _this._influenceLayers = SpriteMaskLayer.Everything, /** @internal */ _this._maskIndex = -1, _this._sprite = null, _this._flipX = false, _this._flipY = false, _this._alphaCutoff = 0.5;
14779
+ return _this;
14780
+ }
14781
+ var _proto = MaskRenderableBase.prototype;
14782
+ /**
14783
+ * @internal
14784
+ */ // @ts-ignore
14785
+ _proto._canBatch = function _canBatch(preElement, curElement) {
14786
+ return VertexMergeBatcher.canBatchSpriteMask(preElement, curElement);
14787
+ };
14788
+ /**
14789
+ * @internal
14790
+ */ // @ts-ignore
14791
+ _proto._batch = function _batch(preElement, curElement) {
14792
+ VertexMergeBatcher.batch(preElement, curElement);
14793
+ };
14794
+ /**
14795
+ * @internal
14796
+ */ // @ts-ignore
14797
+ _proto._onEnableInScene = function _onEnableInScene() {
14798
+ // @ts-ignore
14799
+ Base.prototype._onEnableInScene.call(this);
14800
+ // @ts-ignore
14801
+ this.scene._maskManager.addSpriteMask(this);
14802
+ };
14803
+ /**
14804
+ * @internal
14805
+ */ // @ts-ignore
14806
+ _proto._onDisableInScene = function _onDisableInScene() {
14807
+ // @ts-ignore
14808
+ Base.prototype._onDisableInScene.call(this);
14809
+ // @ts-ignore
14810
+ this.scene._maskManager.removeSpriteMask(this);
14811
+ };
14812
+ /**
14813
+ * @internal
14814
+ */ _proto._containsWorldPoint = function _containsWorldPoint(worldPoint) {
14815
+ return SpriteMaskUtils.containsWorldPoint(worldPoint, this._sprite, this._transformEntity.transform.worldMatrix, this._getSpriteWidth(), this._getSpriteHeight(), this._getSpritePivot(), this._flipX, this._flipY, this._alphaCutoff);
14816
+ };
14817
+ /**
14818
+ * @internal
14819
+ * Initialize shared mask resources. Must be called from subclass constructor.
14820
+ */ _proto._initMask = function _initMask() {
14821
+ exports.SimpleSpriteAssembler.resetData(this);
14822
+ // @ts-ignore
14823
+ this.setMaterial(this._engine._basicResources.spriteMaskDefaultMaterial);
14824
+ // @ts-ignore
14825
+ this.shaderData.setFloat(MaskRenderableBase._alphaCutoffProperty, this._alphaCutoff);
14826
+ this._renderElement = new RenderElement();
14827
+ this._onSpriteChange = this._onSpriteChange.bind(this);
14828
+ };
14829
+ /**
14830
+ * @internal
14831
+ * Clone mask data to target. Called from subclass _cloneTo.
14832
+ */ _proto._cloneMaskData = function _cloneMaskData(target) {
14833
+ target.sprite = this._sprite;
14834
+ };
14835
+ /**
14836
+ * @internal
14837
+ * Release mask sprite resources. Called from subclass _onDestroy.
14838
+ */ _proto._destroyMaskResources = function _destroyMaskResources() {
14839
+ var sprite = this._sprite;
14840
+ if (sprite) {
14841
+ // @ts-ignore
14842
+ this._addResourceReferCount(sprite, -1);
14843
+ sprite._updateFlagManager.removeListener(this._onSpriteChange);
14844
+ }
14845
+ this._sprite = null;
14846
+ this._renderElement = null;
14847
+ };
14848
+ /**
14849
+ * @internal
14850
+ * Update bounds using SimpleSpriteAssembler directly.
14851
+ */ _proto._updateMaskBounds = function _updateMaskBounds(worldBounds) {
14852
+ var sprite = this._sprite;
14853
+ if (sprite) {
14854
+ exports.SimpleSpriteAssembler.updatePositions(this, this._transformEntity.transform.worldMatrix, this._getSpriteWidth(), this._getSpriteHeight(), this._getSpritePivot(), this._flipX, this._flipY);
14855
+ } else {
14856
+ // @ts-ignore
14857
+ var worldPosition = this._transformEntity.transform.worldPosition;
14858
+ worldBounds.min.copyFrom(worldPosition);
14859
+ worldBounds.max.copyFrom(worldPosition);
14860
+ }
14861
+ };
14862
+ /**
14863
+ * @internal
14864
+ * Shared render logic for mask geometry.
14865
+ */ _proto._renderMask = function _renderMask(distanceForSort) {
14866
+ var _this = this, sprite = _this._sprite;
14867
+ var width = this._getSpriteWidth();
14868
+ var height = this._getSpriteHeight();
14869
+ if (!(sprite == null ? void 0 : sprite.texture) || !width || !height) {
14870
+ return;
14871
+ }
14872
+ // @ts-ignore
14873
+ var material = this.getMaterial();
14874
+ if (!material) {
14875
+ return;
14876
+ }
14877
+ if (material.destroyed) {
14878
+ // @ts-ignore
14879
+ material = this._engine._basicResources.spriteMaskDefaultMaterial;
14880
+ }
14881
+ // Update position
14882
+ // @ts-ignore
14883
+ if (this._dirtyUpdateFlag & RendererUpdateFlags.WorldVolume) {
14884
+ exports.SimpleSpriteAssembler.updatePositions(this, this._transformEntity.transform.worldMatrix, width, height, this._getSpritePivot(), this._flipX, this._flipY);
14885
+ // @ts-ignore
14886
+ this._dirtyUpdateFlag &= ~RendererUpdateFlags.WorldVolume;
14887
+ }
14888
+ // Update uv
14889
+ // @ts-ignore
14890
+ if (this._dirtyUpdateFlag & 2) {
14891
+ exports.SimpleSpriteAssembler.updateUVs(this);
14892
+ // @ts-ignore
14893
+ this._dirtyUpdateFlag &= ~2;
14894
+ }
14895
+ var renderElement = this._renderElement;
14896
+ var subChunk = this._subChunk;
14897
+ // @ts-ignore
14898
+ renderElement.set(this, material, subChunk.chunk.primitive, subChunk.subMesh, sprite.texture, subChunk);
14899
+ // @ts-ignore
14900
+ renderElement.priority = this.priority;
14901
+ renderElement.distanceForSort = distanceForSort;
14902
+ renderElement.subShader = material.shader.subShaders[0];
14903
+ };
14904
+ /** @internal */ _proto._onSpriteChange = function _onSpriteChange(type) {
14905
+ switch(type){
14906
+ case SpriteModifyFlags.texture:
14907
+ // @ts-ignore
14908
+ this.shaderData.setTexture(MaskRenderableBase._maskTextureProperty, this.sprite.texture);
14909
+ break;
14910
+ case SpriteModifyFlags.region:
14911
+ case SpriteModifyFlags.atlasRegionOffset:
14912
+ // @ts-ignore
14913
+ this._dirtyUpdateFlag |= 3;
14914
+ break;
14915
+ case SpriteModifyFlags.atlasRegion:
14916
+ // @ts-ignore
14917
+ this._dirtyUpdateFlag |= 2;
14918
+ break;
14919
+ case SpriteModifyFlags.destroy:
14920
+ this.sprite = null;
14921
+ break;
14922
+ default:
14923
+ this._onSpriteChangeExtra(type);
14924
+ break;
14925
+ }
14926
+ };
14927
+ /**
14928
+ * @internal
14929
+ * Hook for subclass-specific sprite change handling.
14930
+ * SpriteMask overrides this to handle size/pivot changes.
14931
+ */ _proto._onSpriteChangeExtra = function _onSpriteChangeExtra(type) {};
14932
+ /** @internal */ _proto._getSpriteWidth = function _getSpriteWidth() {
14933
+ return 0;
14934
+ };
14935
+ /** @internal */ _proto._getSpriteHeight = function _getSpriteHeight() {
14936
+ return 0;
14937
+ };
14938
+ /** @internal */ _proto._getSpritePivot = function _getSpritePivot() {
14939
+ return null;
14940
+ };
14941
+ _create_class$2(MaskRenderableBase, [
14942
+ {
14943
+ key: "influenceLayers",
14944
+ get: /**
14945
+ * The mask layers the sprite mask influence to.
14946
+ */ function get() {
14947
+ return this._influenceLayers;
14948
+ },
14949
+ set: function set(value) {
14950
+ if (this._influenceLayers !== value) {
14951
+ this._influenceLayers = value;
14952
+ // @ts-ignore
14953
+ if (this._phasedActiveInScene) {
14954
+ // @ts-ignore
14955
+ this.scene._maskManager.onMaskInfluenceLayersChange();
14956
+ }
14957
+ }
14958
+ }
14959
+ },
14960
+ {
14961
+ key: "flipX",
14962
+ get: /**
14963
+ * Flips the sprite on the X axis.
14964
+ */ function get() {
14965
+ return this._flipX;
14966
+ },
14967
+ set: function set(value) {
14968
+ if (this._flipX !== value) {
14969
+ this._flipX = value;
14970
+ // @ts-ignore
14971
+ this._dirtyUpdateFlag |= RendererUpdateFlags.WorldVolume;
14972
+ }
14973
+ }
14974
+ },
14975
+ {
14976
+ key: "flipY",
14977
+ get: /**
14978
+ * Flips the sprite on the Y axis.
14979
+ */ function get() {
14980
+ return this._flipY;
14981
+ },
14982
+ set: function set(value) {
14983
+ if (this._flipY !== value) {
14984
+ this._flipY = value;
14985
+ // @ts-ignore
14986
+ this._dirtyUpdateFlag |= RendererUpdateFlags.WorldVolume;
14987
+ }
14988
+ }
14989
+ },
14990
+ {
14991
+ key: "sprite",
14992
+ get: /**
14993
+ * The Sprite to render.
14994
+ */ function get() {
14995
+ return this._sprite;
14996
+ },
14997
+ set: function set(value) {
14998
+ var lastSprite = this._sprite;
14999
+ if (lastSprite !== value) {
15000
+ if (lastSprite) {
15001
+ // @ts-ignore
15002
+ this._addResourceReferCount(lastSprite, -1);
15003
+ lastSprite._updateFlagManager.removeListener(this._onSpriteChange);
15004
+ }
15005
+ // @ts-ignore
15006
+ this._dirtyUpdateFlag |= 11;
15007
+ if (value) {
15008
+ // @ts-ignore
15009
+ this._addResourceReferCount(value, 1);
15010
+ value._updateFlagManager.addListener(this._onSpriteChange);
15011
+ // @ts-ignore
15012
+ this.shaderData.setTexture(MaskRenderableBase._maskTextureProperty, value.texture);
15013
+ } else {
15014
+ // @ts-ignore
15015
+ this.shaderData.setTexture(MaskRenderableBase._maskTextureProperty, null);
15016
+ }
15017
+ this._sprite = value;
15018
+ }
15019
+ }
15020
+ },
15021
+ {
15022
+ key: "alphaCutoff",
15023
+ get: /**
15024
+ * The minimum alpha value used by the mask to select the area of influence defined over the mask's sprite. Value between 0 and 1.
15025
+ */ function get() {
15026
+ return this._alphaCutoff;
15027
+ },
15028
+ set: function set(value) {
15029
+ if (this._alphaCutoff !== value) {
15030
+ this._alphaCutoff = value;
15031
+ // @ts-ignore
15032
+ this.shaderData.setFloat(MaskRenderableBase._alphaCutoffProperty, value);
15033
+ }
15034
+ }
15035
+ }
15036
+ ]);
15037
+ return MaskRenderableBase;
15038
+ }(Base);
15039
+ MaskRenderableBase._maskTextureProperty = ShaderProperty.getByName("renderer_MaskTexture");
15040
+ MaskRenderableBase._alphaCutoffProperty = ShaderProperty.getByName("renderer_MaskAlphaCutoff");
15041
+ __decorate$1([
15042
+ assignmentClone
15043
+ ], MaskRenderableBase.prototype, "_influenceLayers", void 0);
15044
+ __decorate$1([
15045
+ ignoreClone
15046
+ ], MaskRenderableBase.prototype, "_renderElement", void 0);
15047
+ __decorate$1([
15048
+ ignoreClone
15049
+ ], MaskRenderableBase.prototype, "_maskIndex", void 0);
15050
+ __decorate$1([
15051
+ ignoreClone
15052
+ ], MaskRenderableBase.prototype, "_sprite", void 0);
15053
+ __decorate$1([
15054
+ assignmentClone
15055
+ ], MaskRenderableBase.prototype, "_flipX", void 0);
15056
+ __decorate$1([
15057
+ assignmentClone
15058
+ ], MaskRenderableBase.prototype, "_flipY", void 0);
15059
+ __decorate$1([
15060
+ assignmentClone
15061
+ ], MaskRenderableBase.prototype, "_alphaCutoff", void 0);
15062
+ __decorate$1([
15063
+ ignoreClone
15064
+ ], MaskRenderableBase.prototype, "_onSpriteChange", null);
15065
+ return MaskRenderableBase;
15066
+ }
15037
15067
  /**
15038
- * A component for masking Sprites.
15039
- */ var SpriteMask = /*#__PURE__*/ function(Renderer) {
15040
- _inherits$2(SpriteMask, Renderer);
15041
- function SpriteMask(entity) {
15068
+ * @remarks Extends `RendererUpdateFlags`.
15069
+ */ var MaskDirtyFlags = /*#__PURE__*/ function(MaskDirtyFlags) {
15070
+ /** UV. */ MaskDirtyFlags[MaskDirtyFlags["UV"] = 2] = "UV";
15071
+ /** Automatic Size. */ MaskDirtyFlags[MaskDirtyFlags["AutomaticSize"] = 8] = "AutomaticSize";
15072
+ /** WorldVolume and UV. */ MaskDirtyFlags[MaskDirtyFlags["WorldVolumeAndUV"] = 3] = "WorldVolumeAndUV";
15073
+ /** All. */ MaskDirtyFlags[MaskDirtyFlags["All"] = 11] = "All";
15074
+ return MaskDirtyFlags;
15075
+ }({});
15076
+ /**
15077
+ * 2D sprite.
15078
+ */ var Sprite = /*#__PURE__*/ function(ReferResource) {
15079
+ _inherits$2(Sprite, ReferResource);
15080
+ function Sprite(engine, texture, region, pivot, border, name) {
15081
+ if (texture === void 0) texture = null;
15082
+ if (region === void 0) region = null;
15083
+ if (pivot === void 0) pivot = null;
15084
+ if (border === void 0) border = null;
15085
+ if (name === void 0) name = null;
15042
15086
  var _this;
15043
- _this = Renderer.call(this, entity) || this, /** The mask layers the sprite mask influence to. */ _this.influenceLayers = SpriteMaskLayer.Everything, /** @internal */ _this._maskIndex = -1, _this._sprite = null, _this._automaticWidth = 0, _this._automaticHeight = 0, _this._customWidth = undefined, _this._customHeight = undefined, _this._flipX = false, _this._flipY = false, _this._alphaCutoff = 0.5;
15044
- exports.SimpleSpriteAssembler.resetData(_this);
15045
- _this.setMaterial(_this._engine._basicResources.spriteMaskDefaultMaterial);
15046
- _this.shaderData.setFloat(SpriteMask._alphaCutoffProperty, _this._alphaCutoff);
15047
- _this._renderElement = new RenderElement();
15048
- _this._onSpriteChange = _this._onSpriteChange.bind(_this);
15087
+ _this = ReferResource.call(this, engine) || this, _this._automaticWidth = 0, _this._automaticHeight = 0, _this._customWidth = undefined, _this._customHeight = undefined, _this._positions = [
15088
+ new Vector2(),
15089
+ new Vector2(),
15090
+ new Vector2(),
15091
+ new Vector2()
15092
+ ], // 与 SlicedAssembler/TiledAssembler 的 vertex 索引图一致:[0]=LB, [3]=LT, [12]=RB, [15]=RT。
15093
+ // SimpleAssembler 取 [0]/[3]/[12]/[15] 4 个 corner;Sliced/Tiled 用全 16。
15094
+ // prettier-ignore
15095
+ _this._uvs = [
15096
+ new Vector2(),
15097
+ new Vector2(),
15098
+ new Vector2(),
15099
+ new Vector2(),
15100
+ new Vector2(),
15101
+ new Vector2(),
15102
+ new Vector2(),
15103
+ new Vector2(),
15104
+ new Vector2(),
15105
+ new Vector2(),
15106
+ new Vector2(),
15107
+ new Vector2(),
15108
+ new Vector2(),
15109
+ new Vector2(),
15110
+ new Vector2(),
15111
+ new Vector2()
15112
+ ], _this._bounds = new BoundingBox(), _this._texture = null, _this._atlasRotated = false, _this._atlasRegion = new Rect(0, 0, 1, 1), _this._atlasRegionOffset = new Vector4(0, 0, 0, 0), _this._region = new Rect(0, 0, 1, 1), _this._pivot = new Vector2(0.5, 0.5), _this._border = new Vector4(0, 0, 0, 0), _this._dirtyUpdateFlag = 7, /** @internal */ _this._updateFlagManager = new UpdateFlagManager();
15113
+ _this._texture = texture;
15114
+ _this._onRegionChange = _this._onRegionChange.bind(_this);
15115
+ _this._onPivotChange = _this._onPivotChange.bind(_this);
15116
+ _this._onBorderChange = _this._onBorderChange.bind(_this);
15117
+ // @ts-ignore
15118
+ _this._region._onValueChanged = _this._onRegionChange;
15119
+ // @ts-ignore
15120
+ _this._pivot._onValueChanged = _this._onPivotChange;
15121
+ // @ts-ignore
15122
+ _this._border._onValueChanged = _this._onBorderChange;
15123
+ region && _this._region.copyFrom(region);
15124
+ pivot && _this._pivot.copyFrom(pivot);
15125
+ border && _this._border.copyFrom(border);
15126
+ _this.name = name;
15049
15127
  return _this;
15050
15128
  }
15051
- var _proto = SpriteMask.prototype;
15052
- /**
15053
- * @internal
15054
- */ _proto._updateTransformShaderData = function _updateTransformShaderData(context, onlyMVP) {
15055
- //@todo: Always update world positions to buffer, should opt
15056
- this._updateWorldSpaceTransformShaderData(context, onlyMVP);
15057
- };
15129
+ var _proto = Sprite.prototype;
15058
15130
  /**
15059
- * @internal
15060
- */ _proto._cloneTo = function _cloneTo(target) {
15061
- Renderer.prototype._cloneTo.call(this, target);
15062
- target.sprite = this._sprite;
15131
+ * Clone.
15132
+ * @returns Cloned sprite
15133
+ */ _proto.clone = function clone() {
15134
+ var cloneSprite = new Sprite(this._engine, this._texture, this._region, this._pivot, this._border, this.name);
15135
+ cloneSprite._atlasRotated = this._atlasRotated;
15136
+ cloneSprite._atlasRegion.copyFrom(this._atlasRegion);
15137
+ cloneSprite._atlasRegionOffset.copyFrom(this._atlasRegionOffset);
15138
+ return cloneSprite;
15063
15139
  };
15064
15140
  /**
15065
15141
  * @internal
15066
- */ _proto._canBatch = function _canBatch(preElement, curElement) {
15067
- return VertexMergeBatcher.canBatchSpriteMask(preElement, curElement);
15142
+ */ _proto._getPositions = function _getPositions() {
15143
+ this._dirtyUpdateFlag & 1 && this._updatePositions();
15144
+ return this._positions;
15068
15145
  };
15069
15146
  /**
15070
15147
  * @internal
15071
- */ _proto._batch = function _batch(preElement, curElement) {
15072
- VertexMergeBatcher.batch(preElement, curElement);
15148
+ */ _proto._getUVs = function _getUVs() {
15149
+ this._dirtyUpdateFlag & 2 && this._updateUVs();
15150
+ return this._uvs;
15073
15151
  };
15074
15152
  /**
15075
15153
  * @internal
15076
- */ _proto._onEnableInScene = function _onEnableInScene() {
15077
- Renderer.prototype._onEnableInScene.call(this);
15078
- this.scene._maskManager.addSpriteMask(this);
15154
+ */ _proto._getBounds = function _getBounds() {
15155
+ this._dirtyUpdateFlag & 1 && this._updatePositions();
15156
+ return this._bounds;
15079
15157
  };
15080
15158
  /**
15081
15159
  * @internal
15082
- */ _proto._onDisableInScene = function _onDisableInScene() {
15083
- Renderer.prototype._onDisableInScene.call(this);
15084
- this.scene._maskManager.removeSpriteMask(this);
15160
+ */ _proto._addReferCount = function _addReferCount(value) {
15161
+ var _this__atlas;
15162
+ ReferResource.prototype._addReferCount.call(this, value);
15163
+ (_this__atlas = this._atlas) == null ? void 0 : _this__atlas._addReferCount(value);
15085
15164
  };
15086
15165
  /**
15087
15166
  * @internal
15088
- */ _proto._getChunkManager = function _getChunkManager() {
15089
- return this.engine._batcherManager.primitiveChunkManagerMask;
15167
+ */ _proto._onDestroy = function _onDestroy() {
15168
+ this._dispatchSpriteChange(SpriteModifyFlags.destroy);
15169
+ ReferResource.prototype._onDestroy.call(this);
15170
+ this._positions.length = 0;
15171
+ this._positions = null;
15172
+ this._uvs.length = 0;
15173
+ this._uvs = null;
15174
+ this._atlasRegion = null;
15175
+ this._atlasRegionOffset = null;
15176
+ this._region = null;
15177
+ this._pivot = null;
15178
+ this._border = null;
15179
+ this._bounds = null;
15180
+ this._atlas = null;
15181
+ this._texture = null;
15090
15182
  };
15091
- _proto._updateBounds = function _updateBounds(worldBounds) {
15092
- var sprite = this._sprite;
15093
- if (sprite) {
15094
- exports.SimpleSpriteAssembler.updatePositions(this, this._transformEntity.transform.worldMatrix, this.width, this.height, sprite.pivot, this._flipX, this._flipY);
15183
+ _proto._calDefaultSize = function _calDefaultSize() {
15184
+ if (this._texture) {
15185
+ var _this = this, _texture = _this._texture, _atlasRegion = _this._atlasRegion, _atlasRegionOffset = _this._atlasRegionOffset, _region = _this._region, _atlasRotated = _this._atlasRotated;
15186
+ var ppuReciprocal = 1.0 / Engine._pixelsPerUnit;
15187
+ // 先算 atlas 中绝对像素(texture 不一定是方形,必须各自乘对应维度)
15188
+ var atlasPxW = _texture.width * _atlasRegion.width;
15189
+ var atlasPxH = _texture.height * _atlasRegion.height;
15190
+ // atlas 顺时针 pack 90°:原图 W×H 在 atlas 中占 H×W 区域,仅交换 atlasPx 的 W/H
15191
+ var originWidth = _atlasRotated ? atlasPxH : atlasPxW;
15192
+ var originHeight = _atlasRotated ? atlasPxW : atlasPxH;
15193
+ this._automaticWidth = originWidth / (1 - _atlasRegionOffset.x - _atlasRegionOffset.z) * _region.width * ppuReciprocal;
15194
+ this._automaticHeight = originHeight / (1 - _atlasRegionOffset.y - _atlasRegionOffset.w) * _region.height * ppuReciprocal;
15095
15195
  } else {
15096
- var worldPosition = this._transformEntity.transform.worldPosition;
15097
- worldBounds.min.copyFrom(worldPosition);
15098
- worldBounds.max.copyFrom(worldPosition);
15196
+ this._automaticWidth = this._automaticHeight = 0;
15099
15197
  }
15198
+ this._dirtyUpdateFlag &= ~4;
15100
15199
  };
15101
- /**
15102
- * @inheritdoc
15103
- */ _proto._render = function _render(context) {
15104
- var _this = this, sprite = _this._sprite;
15105
- if (!(sprite == null ? void 0 : sprite.texture) || !this.width || !this.height) {
15106
- return;
15107
- }
15108
- var material = this.getMaterial();
15109
- if (!material) {
15110
- return;
15111
- }
15112
- var _this1 = this, engine = _this1._engine;
15113
- // @todo: This question needs to be raised rather than hidden.
15114
- if (material.destroyed) {
15115
- material = engine._basicResources.spriteMaskDefaultMaterial;
15116
- }
15117
- // Update position
15118
- if (this._dirtyUpdateFlag & RendererUpdateFlags.WorldVolume) {
15119
- exports.SimpleSpriteAssembler.updatePositions(this, this._transformEntity.transform.worldMatrix, this.width, this.height, sprite.pivot, this._flipX, this._flipY);
15120
- this._dirtyUpdateFlag &= ~RendererUpdateFlags.WorldVolume;
15121
- }
15122
- // Update uv
15123
- if (this._dirtyUpdateFlag & 2) {
15124
- exports.SimpleSpriteAssembler.updateUVs(this);
15125
- this._dirtyUpdateFlag &= ~2;
15126
- }
15127
- var renderElement = this._renderElement;
15128
- var subChunk = this._subChunk;
15129
- renderElement.set(this, material, subChunk.chunk.primitive, subChunk.subMesh, this.sprite.texture, subChunk);
15130
- renderElement.priority = this.priority;
15131
- renderElement.distanceForSort = this._distanceForSort;
15132
- renderElement.subShader = material.shader.subShaders[0];
15200
+ _proto._updatePositions = function _updatePositions() {
15201
+ var blank = this._atlasRegionOffset;
15202
+ var _this__region = this._region, regionX = _this__region.x, regionY = _this__region.y, regionW = _this__region.width, regionH = _this__region.height;
15203
+ var regionRight = 1 - regionX - regionW;
15204
+ var regionBottom = 1 - regionY - regionH;
15205
+ var left = Math.max(blank.x - regionX, 0) / regionW;
15206
+ var bottom = Math.max(blank.w - regionY, 0) / regionH;
15207
+ var right = 1 - Math.max(blank.z - regionRight, 0) / regionW;
15208
+ var top = 1 - Math.max(blank.y - regionBottom, 0) / regionH;
15209
+ // Update positions.
15210
+ // ---------------
15211
+ // 2 - 3
15212
+ // | |
15213
+ // 0 - 1
15214
+ // ---------------
15215
+ var positions = this._positions;
15216
+ positions[0].set(left, bottom);
15217
+ positions[1].set(right, bottom);
15218
+ positions[2].set(left, top);
15219
+ positions[3].set(right, top);
15220
+ var bounds = this._bounds;
15221
+ bounds.min.set(left, bottom, 0);
15222
+ bounds.max.set(right, top, 0);
15223
+ this._dirtyUpdateFlag &= ~1;
15133
15224
  };
15134
- /**
15135
- * @inheritdoc
15136
- */ _proto._onDestroy = function _onDestroy() {
15137
- var sprite = this._sprite;
15138
- if (sprite) {
15139
- this._addResourceReferCount(sprite, -1);
15140
- sprite._updateFlagManager.removeListener(this._onSpriteChange);
15141
- }
15142
- Renderer.prototype._onDestroy.call(this);
15143
- this._sprite = null;
15144
- if (this._subChunk) {
15145
- this._getChunkManager().freeSubChunk(this._subChunk);
15146
- this._subChunk = null;
15225
+ _proto._updateUVs = function _updateUVs() {
15226
+ var _this = this, uvs = _this._uvs, atlasRotated = _this._atlasRotated, border = _this._border;
15227
+ var _this__region = this._region, regionLeft = _this__region.x, regionTop = _this__region.y, regionW = _this__region.width, regionH = _this__region.height;
15228
+ var regionRight = 1 - regionLeft - regionW;
15229
+ var regionBottom = 1 - regionTop - regionH;
15230
+ var _this__atlasRegion = this._atlasRegion, atlasRegionX = _this__atlasRegion.x, atlasRegionY = _this__atlasRegion.y, atlasRegionW = _this__atlasRegion.width, atlasRegionH = _this__atlasRegion.height;
15231
+ var _this__atlasRegionOffset = this._atlasRegionOffset, offsetLeft = _this__atlasRegionOffset.x, offsetTop = _this__atlasRegionOffset.y, offsetRight = _this__atlasRegionOffset.z, offsetBottom = _this__atlasRegionOffset.w;
15232
+ var realWidth = atlasRegionW / (1 - offsetLeft - offsetRight);
15233
+ var realHeight = atlasRegionH / (1 - offsetTop - offsetBottom);
15234
+ // 4 个外边界 + 4 个 9-slice 内边界
15235
+ var left, top, right, bottom;
15236
+ var bLeft, bTop, bRight, bBottom;
15237
+ if (atlasRotated) {
15238
+ // 原图 region/offset (left/top/right/bottom) 在 atlas 中映射为 (bottom/left/top/right)
15239
+ left = Math.max(regionBottom - offsetLeft, 0) * realWidth + atlasRegionX;
15240
+ top = Math.max(regionLeft - offsetTop, 0) * realHeight + atlasRegionY;
15241
+ right = atlasRegionW + atlasRegionX - Math.max(regionTop - offsetRight, 0) * realWidth;
15242
+ bottom = atlasRegionH + atlasRegionY - Math.max(regionRight - offsetBottom, 0) * realHeight;
15243
+ bLeft = (regionBottom - offsetLeft + border.y * regionH) * realWidth + atlasRegionX;
15244
+ bTop = (regionLeft - offsetTop + border.x * regionW) * realHeight + atlasRegionY;
15245
+ bRight = atlasRegionW + atlasRegionX - (regionTop - offsetRight + border.w * regionH) * realWidth;
15246
+ bBottom = atlasRegionH + atlasRegionY - (regionRight - offsetBottom + border.z * regionW) * realHeight;
15247
+ } else {
15248
+ left = Math.max(regionLeft - offsetLeft, 0) * realWidth + atlasRegionX;
15249
+ top = Math.max(regionBottom - offsetTop, 0) * realHeight + atlasRegionY;
15250
+ right = atlasRegionW + atlasRegionX - Math.max(regionRight - offsetRight, 0) * realWidth;
15251
+ bottom = atlasRegionH + atlasRegionY - Math.max(regionTop - offsetBottom, 0) * realHeight;
15252
+ bLeft = (regionLeft - offsetLeft + border.x * regionW) * realWidth + atlasRegionX;
15253
+ bTop = (regionBottom - offsetTop + border.w * regionH) * realHeight + atlasRegionY;
15254
+ bRight = atlasRegionW + atlasRegionX - (regionRight - offsetRight + border.z * regionW) * realWidth;
15255
+ bBottom = atlasRegionH + atlasRegionY - (regionTop - offsetBottom + border.y * regionH) * realHeight;
15147
15256
  }
15148
- this._renderElement = null;
15149
- };
15150
- _proto._calDefaultSize = function _calDefaultSize() {
15151
- var sprite = this._sprite;
15152
- if (sprite) {
15153
- this._automaticWidth = sprite.width;
15154
- this._automaticHeight = sprite.height;
15257
+ // 16 UV 网格填充(column-major:index=i*4+j,i=column[0=left..3=right],j=row[0=bottom..3=top])
15258
+ // - 非 rotated:column 决定 atlas X (left/bLeft/bRight/right),row 决定 atlas Y (bottom/bBottom/bTop/top)
15259
+ // - rotated 90° 顺时针 packed:display column 对应 atlas Y 的反向(顶→底),display row 对应 atlas X
15260
+ if (atlasRotated) {
15261
+ uvs[0].set(left, top), uvs[1].set(bLeft, top), uvs[2].set(bRight, top), uvs[3].set(right, top);
15262
+ uvs[4].set(left, bTop), uvs[5].set(bLeft, bTop), uvs[6].set(bRight, bTop), uvs[7].set(right, bTop);
15263
+ uvs[8].set(left, bBottom), uvs[9].set(bLeft, bBottom), uvs[10].set(bRight, bBottom), uvs[11].set(right, bBottom);
15264
+ uvs[12].set(left, bottom), uvs[13].set(bLeft, bottom), uvs[14].set(bRight, bottom), uvs[15].set(right, bottom);
15155
15265
  } else {
15156
- this._automaticWidth = this._automaticHeight = 0;
15266
+ uvs[0].set(left, bottom), uvs[1].set(left, bBottom), uvs[2].set(left, bTop), uvs[3].set(left, top);
15267
+ uvs[4].set(bLeft, bottom), uvs[5].set(bLeft, bBottom), uvs[6].set(bLeft, bTop), uvs[7].set(bLeft, top);
15268
+ uvs[8].set(bRight, bottom), uvs[9].set(bRight, bBottom), uvs[10].set(bRight, bTop), uvs[11].set(bRight, top);
15269
+ uvs[12].set(right, bottom), uvs[13].set(right, bBottom), uvs[14].set(right, bTop), uvs[15].set(right, top);
15157
15270
  }
15158
- this._dirtyUpdateFlag &= ~4;
15271
+ this._dirtyUpdateFlag &= ~2;
15159
15272
  };
15160
- _proto._onSpriteChange = function _onSpriteChange(type) {
15273
+ _proto._dispatchSpriteChange = function _dispatchSpriteChange(type) {
15161
15274
  switch(type){
15162
15275
  case SpriteModifyFlags.texture:
15163
- this.shaderData.setTexture(SpriteMask._textureProperty, this.sprite.texture);
15164
- break;
15165
- case SpriteModifyFlags.size:
15166
15276
  this._dirtyUpdateFlag |= 4;
15167
- if (this._customWidth === undefined || this._customHeight === undefined) {
15168
- this._dirtyUpdateFlag |= RendererUpdateFlags.WorldVolume;
15169
- }
15170
15277
  break;
15171
- case SpriteModifyFlags.region:
15172
15278
  case SpriteModifyFlags.atlasRegionOffset:
15173
- this._dirtyUpdateFlag |= 3;
15279
+ case SpriteModifyFlags.region:
15280
+ this._dirtyUpdateFlag |= 7;
15174
15281
  break;
15175
15282
  case SpriteModifyFlags.atlasRegion:
15176
- this._dirtyUpdateFlag |= 2;
15177
- break;
15178
- case SpriteModifyFlags.pivot:
15179
- this._dirtyUpdateFlag |= RendererUpdateFlags.WorldVolume;
15283
+ this._dirtyUpdateFlag |= 4 | 2;
15180
15284
  break;
15181
- case SpriteModifyFlags.destroy:
15182
- this.sprite = null;
15285
+ case SpriteModifyFlags.border:
15286
+ this._dirtyUpdateFlag |= 2;
15183
15287
  break;
15184
15288
  }
15289
+ this._updateFlagManager.dispatch(type);
15185
15290
  };
15186
- _create_class$2(SpriteMask, [
15291
+ _proto._onRegionChange = function _onRegionChange() {
15292
+ var _this = this, region = _this._region;
15293
+ // @ts-ignore
15294
+ region._onValueChanged = null;
15295
+ var x = MathUtil.clamp(region.x, 0, 1);
15296
+ var y = MathUtil.clamp(region.y, 0, 1);
15297
+ region.set(x, y, MathUtil.clamp(region.width, 0, 1 - x), MathUtil.clamp(region.height, 0, 1 - y));
15298
+ this._dispatchSpriteChange(SpriteModifyFlags.region);
15299
+ if (this._customWidth === undefined || this._customHeight === undefined) {
15300
+ this._dispatchSpriteChange(SpriteModifyFlags.size);
15301
+ }
15302
+ // @ts-ignore
15303
+ region._onValueChanged = this._onRegionChange;
15304
+ };
15305
+ _proto._onPivotChange = function _onPivotChange() {
15306
+ this._dispatchSpriteChange(SpriteModifyFlags.pivot);
15307
+ };
15308
+ _proto._onBorderChange = function _onBorderChange() {
15309
+ var _this = this, border = _this._border;
15310
+ // @ts-ignore
15311
+ border._onValueChanged = null;
15312
+ var x = MathUtil.clamp(border.x, 0, 1);
15313
+ var y = MathUtil.clamp(border.y, 0, 1);
15314
+ border.set(x, y, MathUtil.clamp(border.z, 0, 1 - x), MathUtil.clamp(border.w, 0, 1 - y));
15315
+ this._dispatchSpriteChange(SpriteModifyFlags.border);
15316
+ // @ts-ignore
15317
+ border._onValueChanged = this._onBorderChange;
15318
+ };
15319
+ _create_class$2(Sprite, [
15320
+ {
15321
+ key: "texture",
15322
+ get: /**
15323
+ * The reference to the used texture.
15324
+ */ function get() {
15325
+ return this._texture;
15326
+ },
15327
+ set: function set(value) {
15328
+ if (this._texture !== value) {
15329
+ this._texture = value;
15330
+ this._dispatchSpriteChange(SpriteModifyFlags.texture);
15331
+ if (this._customWidth === undefined || this._customHeight === undefined) {
15332
+ this._dispatchSpriteChange(SpriteModifyFlags.size);
15333
+ }
15334
+ }
15335
+ }
15336
+ },
15187
15337
  {
15188
15338
  key: "width",
15189
15339
  get: /**
15190
- * Render width (in world coordinates).
15340
+ * The width of the sprite (in world coordinates).
15191
15341
  *
15192
15342
  * @remarks
15193
15343
  * If width is set, return the set value,
15194
- * otherwise return `SpriteMask.sprite.width`.
15344
+ * otherwise return the width calculated according to `Texture.width`, `Sprite.region`, `Sprite.atlasRegion` and `Sprite.atlasRegionOffset`.
15195
15345
  */ function get() {
15196
15346
  if (this._customWidth !== undefined) {
15197
15347
  return this._customWidth;
@@ -15203,18 +15353,18 @@
15203
15353
  set: function set(value) {
15204
15354
  if (this._customWidth !== value) {
15205
15355
  this._customWidth = value;
15206
- this._dirtyUpdateFlag |= RendererUpdateFlags.WorldVolume;
15356
+ this._dispatchSpriteChange(SpriteModifyFlags.size);
15207
15357
  }
15208
15358
  }
15209
15359
  },
15210
15360
  {
15211
15361
  key: "height",
15212
15362
  get: /**
15213
- * Render height (in world coordinates).
15363
+ * The height of the sprite (in world coordinates).
15214
15364
  *
15215
15365
  * @remarks
15216
15366
  * If height is set, return the set value,
15217
- * otherwise return `SpriteMask.sprite.height`.
15367
+ * otherwise return the height calculated according to `Texture.height`, `Sprite.region`, `Sprite.atlasRegion` and `Sprite.atlasRegionOffset`.
15218
15368
  */ function get() {
15219
15369
  if (this._customHeight !== undefined) {
15220
15370
  return this._customHeight;
@@ -15226,98 +15376,241 @@
15226
15376
  set: function set(value) {
15227
15377
  if (this._customHeight !== value) {
15228
15378
  this._customHeight = value;
15229
- this._dirtyUpdateFlag |= RendererUpdateFlags.WorldVolume;
15379
+ this._dispatchSpriteChange(SpriteModifyFlags.size);
15230
15380
  }
15231
15381
  }
15232
15382
  },
15233
15383
  {
15234
- key: "flipX",
15384
+ key: "atlasRotated",
15235
15385
  get: /**
15236
- * Flips the sprite on the X axis.
15386
+ * Is it rotated 90 degrees clockwise when packing.
15237
15387
  */ function get() {
15238
- return this._flipX;
15388
+ return this._atlasRotated;
15239
15389
  },
15240
15390
  set: function set(value) {
15241
- if (this._flipX !== value) {
15242
- this._flipX = value;
15243
- this._dirtyUpdateFlag |= RendererUpdateFlags.WorldVolume;
15391
+ if (this._atlasRotated != value) {
15392
+ this._atlasRotated = value;
15244
15393
  }
15245
15394
  }
15246
15395
  },
15247
15396
  {
15248
- key: "flipY",
15397
+ key: "atlasRegion",
15249
15398
  get: /**
15250
- * Flips the sprite on the Y axis.
15399
+ * The rectangle region of the original texture on its atlas texture, specified in normalized.
15251
15400
  */ function get() {
15252
- return this._flipY;
15401
+ return this._atlasRegion;
15253
15402
  },
15254
15403
  set: function set(value) {
15255
- if (this._flipY !== value) {
15256
- this._flipY = value;
15257
- this._dirtyUpdateFlag |= RendererUpdateFlags.WorldVolume;
15404
+ var x = MathUtil.clamp(value.x, 0, 1);
15405
+ var y = MathUtil.clamp(value.y, 0, 1);
15406
+ this._atlasRegion.set(x, y, MathUtil.clamp(value.width, 0, 1 - x), MathUtil.clamp(value.height, 0, 1 - y));
15407
+ this._dispatchSpriteChange(SpriteModifyFlags.atlasRegion);
15408
+ if (this._customWidth === undefined || this._customHeight === undefined) {
15409
+ this._dispatchSpriteChange(SpriteModifyFlags.size);
15258
15410
  }
15259
15411
  }
15260
15412
  },
15261
15413
  {
15262
- key: "sprite",
15414
+ key: "atlasRegionOffset",
15263
15415
  get: /**
15264
- * The Sprite to render.
15416
+ * The rectangle region offset of the original texture on its atlas texture, specified in normalized.
15265
15417
  */ function get() {
15266
- return this._sprite;
15418
+ return this._atlasRegionOffset;
15267
15419
  },
15268
15420
  set: function set(value) {
15269
- var lastSprite = this._sprite;
15270
- if (lastSprite !== value) {
15271
- if (lastSprite) {
15272
- this._addResourceReferCount(lastSprite, -1);
15273
- lastSprite._updateFlagManager.removeListener(this._onSpriteChange);
15274
- }
15275
- this._dirtyUpdateFlag |= 7;
15276
- if (value) {
15277
- this._addResourceReferCount(value, 1);
15278
- value._updateFlagManager.addListener(this._onSpriteChange);
15279
- this.shaderData.setTexture(SpriteMask._textureProperty, value.texture);
15280
- } else {
15281
- this.shaderData.setTexture(SpriteMask._textureProperty, null);
15282
- }
15283
- this._sprite = value;
15421
+ var x = MathUtil.clamp(value.x, 0, 1);
15422
+ var y = MathUtil.clamp(value.y, 0, 1);
15423
+ this._atlasRegionOffset.set(x, y, MathUtil.clamp(value.z, 0, 1 - x), MathUtil.clamp(value.w, 0, 1 - y));
15424
+ this._dispatchSpriteChange(SpriteModifyFlags.atlasRegionOffset);
15425
+ if (this._customWidth === undefined || this._customHeight === undefined) {
15426
+ this._dispatchSpriteChange(SpriteModifyFlags.size);
15284
15427
  }
15285
15428
  }
15286
15429
  },
15287
15430
  {
15288
- key: "alphaCutoff",
15431
+ key: "region",
15289
15432
  get: /**
15290
- * The minimum alpha value used by the mask to select the area of influence defined over the mask's sprite. Value between 0 and 1.
15433
+ * The rectangle region of the sprite, specified in normalized.
15291
15434
  */ function get() {
15292
- return this._alphaCutoff;
15435
+ return this._region;
15293
15436
  },
15294
15437
  set: function set(value) {
15295
- if (this._alphaCutoff !== value) {
15296
- this._alphaCutoff = value;
15297
- this.shaderData.setFloat(SpriteMask._alphaCutoffProperty, value);
15298
- }
15438
+ this._region !== value && this._region.copyFrom(value);
15439
+ }
15440
+ },
15441
+ {
15442
+ key: "pivot",
15443
+ get: /**
15444
+ * Location of the sprite's center point in the rectangle region, specified in normalized.
15445
+ * The origin is at the bottom left and the default value is (0.5, 0.5).
15446
+ */ function get() {
15447
+ return this._pivot;
15448
+ },
15449
+ set: function set(value) {
15450
+ this._pivot !== value && this._pivot.copyFrom(value);
15451
+ }
15452
+ },
15453
+ {
15454
+ key: "border",
15455
+ get: /**
15456
+ * Get the border of the sprite.
15457
+ * x y z w
15458
+ * | | | |
15459
+ * Left, bottom, right, top.
15460
+ * @remarks only use in sliced mode.
15461
+ */ function get() {
15462
+ return this._border;
15463
+ },
15464
+ set: function set(value) {
15465
+ this._border !== value && this._border.copyFrom(value);
15299
15466
  }
15300
15467
  }
15301
15468
  ]);
15302
- return SpriteMask;
15303
- }(exports.Renderer);
15304
- /** @internal */ SpriteMask._textureProperty = ShaderProperty.getByName("renderer_MaskTexture");
15305
- /** @internal */ SpriteMask._alphaCutoffProperty = ShaderProperty.getByName("renderer_MaskAlphaCutoff");
15306
- __decorate$1([
15307
- assignmentClone
15308
- ], SpriteMask.prototype, "influenceLayers", void 0);
15469
+ return Sprite;
15470
+ }(ReferResource);
15309
15471
  __decorate$1([
15310
15472
  ignoreClone
15311
- ], SpriteMask.prototype, "_renderElement", void 0);
15473
+ ], Sprite.prototype, "_onRegionChange", null);
15312
15474
  __decorate$1([
15313
15475
  ignoreClone
15314
- ], SpriteMask.prototype, "_subChunk", void 0);
15476
+ ], Sprite.prototype, "_onPivotChange", null);
15315
15477
  __decorate$1([
15316
15478
  ignoreClone
15317
- ], SpriteMask.prototype, "_maskIndex", void 0);
15479
+ ], Sprite.prototype, "_onBorderChange", null);
15480
+ /**
15481
+ * A component for masking Sprites.
15482
+ */ var SpriteMask = /*#__PURE__*/ function(_MaskRenderable) {
15483
+ _inherits$2(SpriteMask, _MaskRenderable);
15484
+ function SpriteMask(entity) {
15485
+ var _this;
15486
+ _this = _MaskRenderable.call(this, entity) || this, _this._automaticWidth = 0, _this._automaticHeight = 0, _this._customWidth = undefined, _this._customHeight = undefined;
15487
+ _this._initMask();
15488
+ return _this;
15489
+ }
15490
+ var _proto = SpriteMask.prototype;
15491
+ /**
15492
+ * @internal
15493
+ */ _proto._updateTransformShaderData = function _updateTransformShaderData(context, onlyMVP) {
15494
+ //@todo: Always update world positions to buffer, should opt
15495
+ this._updateWorldSpaceTransformShaderData(context, onlyMVP);
15496
+ };
15497
+ /**
15498
+ * @internal
15499
+ */ _proto._cloneTo = function _cloneTo(target) {
15500
+ _MaskRenderable.prototype._cloneTo.call(this, target);
15501
+ this._cloneMaskData(target);
15502
+ };
15503
+ /**
15504
+ * @internal
15505
+ */ _proto._getChunkManager = function _getChunkManager() {
15506
+ return this.engine._batcherManager.primitiveChunkManagerMask;
15507
+ };
15508
+ _proto._updateBounds = function _updateBounds(worldBounds) {
15509
+ this._updateMaskBounds(worldBounds);
15510
+ };
15511
+ /**
15512
+ * @inheritdoc
15513
+ */ _proto._render = function _render(context) {
15514
+ this._renderMask(this._distanceForSort);
15515
+ };
15516
+ /**
15517
+ * @inheritdoc
15518
+ */ _proto._onDestroy = function _onDestroy() {
15519
+ this._destroyMaskResources();
15520
+ _MaskRenderable.prototype._onDestroy.call(this);
15521
+ if (this._subChunk) {
15522
+ this._getChunkManager().freeSubChunk(this._subChunk);
15523
+ this._subChunk = null;
15524
+ }
15525
+ };
15526
+ _proto._getSpriteWidth = function _getSpriteWidth() {
15527
+ return this.width;
15528
+ };
15529
+ _proto._getSpriteHeight = function _getSpriteHeight() {
15530
+ return this.height;
15531
+ };
15532
+ _proto._getSpritePivot = function _getSpritePivot() {
15533
+ var _this_sprite;
15534
+ return (_this_sprite = this.sprite) == null ? void 0 : _this_sprite.pivot;
15535
+ };
15536
+ _proto._onSpriteChangeExtra = function _onSpriteChangeExtra(type) {
15537
+ switch(type){
15538
+ case SpriteModifyFlags.size:
15539
+ this._dirtyUpdateFlag |= MaskDirtyFlags.AutomaticSize;
15540
+ if (this._customWidth === undefined || this._customHeight === undefined) {
15541
+ this._dirtyUpdateFlag |= RendererUpdateFlags.WorldVolume;
15542
+ }
15543
+ break;
15544
+ case SpriteModifyFlags.pivot:
15545
+ this._dirtyUpdateFlag |= RendererUpdateFlags.WorldVolume;
15546
+ break;
15547
+ }
15548
+ };
15549
+ _proto._calDefaultSize = function _calDefaultSize() {
15550
+ var sprite = this.sprite;
15551
+ if (sprite) {
15552
+ this._automaticWidth = sprite.width;
15553
+ this._automaticHeight = sprite.height;
15554
+ } else {
15555
+ this._automaticWidth = this._automaticHeight = 0;
15556
+ }
15557
+ this._dirtyUpdateFlag &= ~MaskDirtyFlags.AutomaticSize;
15558
+ };
15559
+ _create_class$2(SpriteMask, [
15560
+ {
15561
+ key: "width",
15562
+ get: /**
15563
+ * Render width (in world coordinates).
15564
+ *
15565
+ * @remarks
15566
+ * If width is set, return the set value,
15567
+ * otherwise return `SpriteMask.sprite.width`.
15568
+ */ function get() {
15569
+ if (this._customWidth !== undefined) {
15570
+ return this._customWidth;
15571
+ } else {
15572
+ this._dirtyUpdateFlag & MaskDirtyFlags.AutomaticSize && this._calDefaultSize();
15573
+ return this._automaticWidth;
15574
+ }
15575
+ },
15576
+ set: function set(value) {
15577
+ if (this._customWidth !== value) {
15578
+ this._customWidth = value;
15579
+ this._dirtyUpdateFlag |= RendererUpdateFlags.WorldVolume;
15580
+ }
15581
+ }
15582
+ },
15583
+ {
15584
+ key: "height",
15585
+ get: /**
15586
+ * Render height (in world coordinates).
15587
+ *
15588
+ * @remarks
15589
+ * If height is set, return the set value,
15590
+ * otherwise return `SpriteMask.sprite.height`.
15591
+ */ function get() {
15592
+ if (this._customHeight !== undefined) {
15593
+ return this._customHeight;
15594
+ } else {
15595
+ this._dirtyUpdateFlag & MaskDirtyFlags.AutomaticSize && this._calDefaultSize();
15596
+ return this._automaticHeight;
15597
+ }
15598
+ },
15599
+ set: function set(value) {
15600
+ if (this._customHeight !== value) {
15601
+ this._customHeight = value;
15602
+ this._dirtyUpdateFlag |= RendererUpdateFlags.WorldVolume;
15603
+ }
15604
+ }
15605
+ }
15606
+ ]);
15607
+ return SpriteMask;
15608
+ }(MaskRenderable(exports.Renderer));
15609
+ /** @internal */ SpriteMask._alphaCutoffProperty = ShaderProperty.getByName("renderer_MaskAlphaCutoff");
15610
+ /** @internal */ SpriteMask._textureProperty = ShaderProperty.getByName("renderer_MaskTexture");
15318
15611
  __decorate$1([
15319
15612
  ignoreClone
15320
- ], SpriteMask.prototype, "_sprite", void 0);
15613
+ ], SpriteMask.prototype, "_subChunk", void 0);
15321
15614
  __decorate$1([
15322
15615
  ignoreClone
15323
15616
  ], SpriteMask.prototype, "_automaticWidth", void 0);
@@ -15330,18 +15623,6 @@
15330
15623
  __decorate$1([
15331
15624
  assignmentClone
15332
15625
  ], SpriteMask.prototype, "_customHeight", void 0);
15333
- __decorate$1([
15334
- assignmentClone
15335
- ], SpriteMask.prototype, "_flipX", void 0);
15336
- __decorate$1([
15337
- assignmentClone
15338
- ], SpriteMask.prototype, "_flipY", void 0);
15339
- __decorate$1([
15340
- assignmentClone
15341
- ], SpriteMask.prototype, "_alphaCutoff", void 0);
15342
- __decorate$1([
15343
- ignoreClone
15344
- ], SpriteMask.prototype, "_onSpriteChange", null);
15345
15626
  /**
15346
15627
  * Renders a Sprite for 2D graphics.
15347
15628
  */ var SpriteRenderer = /*#__PURE__*/ function(Renderer) {
@@ -16150,6 +16431,7 @@
16150
16431
  if (charLength > 0) {
16151
16432
  this._buildChunk(curTextChunk, charLength);
16152
16433
  }
16434
+ this._setDirtyFlagTrue(4);
16153
16435
  charRenderInfos.length = 0;
16154
16436
  };
16155
16437
  _proto._onTransformChanged = function _onTransformChanged(bit) {
@@ -29344,8 +29626,8 @@
29344
29626
  var spriteMaskVs = "uniform mat4 camera_VPMat;\n\nattribute vec3 POSITION;\nattribute vec2 TEXCOORD_0;\n\nvarying vec2 v_uv;\n\nvoid main()\n{\n gl_Position = camera_VPMat * vec4(POSITION, 1.0);\n v_uv = TEXCOORD_0;\n}\n"; // eslint-disable-line
29345
29627
  var spriteFs = "#include <common>\nuniform sampler2D renderer_SpriteTexture;\n\nvarying vec2 v_uv;\nvarying vec4 v_color;\n\nvoid main()\n{\n vec4 baseColor = texture2DSRGB(renderer_SpriteTexture, v_uv);\n gl_FragColor = baseColor * v_color;\n}\n"; // eslint-disable-line
29346
29628
  var spriteVs = "uniform mat4 renderer_MVPMat;\n\nattribute vec3 POSITION;\nattribute vec2 TEXCOORD_0;\nattribute vec4 COLOR_0;\n\nvarying vec2 v_uv;\nvarying vec4 v_color;\n\nvoid main()\n{\n gl_Position = renderer_MVPMat * vec4(POSITION, 1.0);\n\n v_uv = TEXCOORD_0;\n v_color = COLOR_0;\n}\n"; // eslint-disable-line
29347
- var textFs = "uniform sampler2D renderElement_TextTexture;\n\nvarying vec2 v_uv;\nvarying vec4 v_color;\n\nvoid main()\n{\n vec4 texColor = texture2D(renderElement_TextTexture, v_uv);\n #ifdef GRAPHICS_API_WEBGL2\n float coverage = texColor.r;\n #else\n float coverage = texColor.a;\n #endif\n gl_FragColor = vec4(v_color.rgb, v_color.a * coverage);\n}\n"; // eslint-disable-line
29348
- var textVs = "uniform mat4 renderer_MVPMat;\n\nattribute vec3 POSITION;\nattribute vec2 TEXCOORD_0;\nattribute vec4 COLOR_0;\n\nvarying vec2 v_uv;\nvarying vec4 v_color;\n\nvoid main()\n{\n gl_Position = renderer_MVPMat * vec4(POSITION, 1.0);\n\n v_uv = TEXCOORD_0;\n v_color = COLOR_0;\n}\n"; // eslint-disable-line
29629
+ var textFs = "uniform sampler2D renderElement_TextTexture;\nuniform vec4 renderer_UIRectClipRect;\nuniform float renderer_UIRectClipEnabled;\nuniform vec4 renderer_UIRectClipSoftness;\nuniform float renderer_UIRectClipHardClip;\n\nvarying vec2 v_uv;\nvarying vec4 v_color;\nvarying vec2 v_worldPosition;\n\nfloat getUIRectClipAlpha()\n{\n vec4 edgeDistance = vec4(\n v_worldPosition.x - renderer_UIRectClipRect.x,\n v_worldPosition.y - renderer_UIRectClipRect.y,\n renderer_UIRectClipRect.z - v_worldPosition.x,\n renderer_UIRectClipRect.w - v_worldPosition.y\n );\n vec4 hardClipFactor = step(vec4(0.0), edgeDistance);\n vec4 softness = max(renderer_UIRectClipSoftness, vec4(1e-5));\n vec4 softClipFactor = clamp(edgeDistance / softness, 0.0, 1.0);\n vec4 useSoftness = step(vec4(1e-5), renderer_UIRectClipSoftness);\n vec4 clipFactor = mix(hardClipFactor, softClipFactor, useSoftness);\n return clipFactor.x * clipFactor.y * clipFactor.z * clipFactor.w;\n}\n\nvoid main()\n{\n float rectClipAlpha = 1.0;\n if (renderer_UIRectClipEnabled > 0.5) {\n rectClipAlpha = getUIRectClipAlpha();\n }\n\n vec4 texColor = texture2D(renderElement_TextTexture, v_uv);\n #ifdef GRAPHICS_API_WEBGL2\n float coverage = texColor.r;\n #else\n float coverage = texColor.a;\n #endif\n vec4 finalColor = vec4(v_color.rgb, v_color.a * coverage);\n finalColor.a *= rectClipAlpha;\n if (renderer_UIRectClipEnabled > 0.5 && renderer_UIRectClipHardClip > 0.5 && finalColor.a < 0.001) {\n discard;\n }\n gl_FragColor = finalColor;\n}\n"; // eslint-disable-line
29630
+ var textVs = "uniform mat4 renderer_MVPMat;\nuniform mat4 renderer_ModelMat;\n\nattribute vec3 POSITION;\nattribute vec2 TEXCOORD_0;\nattribute vec4 COLOR_0;\n\nvarying vec2 v_uv;\nvarying vec4 v_color;\nvarying vec2 v_worldPosition;\n\nvoid main()\n{\n gl_Position = renderer_MVPMat * vec4(POSITION, 1.0);\n\n v_uv = TEXCOORD_0;\n v_color = COLOR_0;\n v_worldPosition = POSITION.xy;\n}\n"; // eslint-disable-line
29349
29631
  var trailFs = "#include <common>\n\nvarying vec2 v_uv;\nvarying vec4 v_color;\n\nuniform vec4 material_BaseColor;\n\n#ifdef MATERIAL_HAS_BASETEXTURE\n uniform sampler2D material_BaseTexture;\n#endif\n\nuniform mediump vec3 material_EmissiveColor;\n#ifdef MATERIAL_HAS_EMISSIVETEXTURE\n uniform sampler2D material_EmissiveTexture;\n#endif\n\nvoid main() {\n vec4 color = material_BaseColor * v_color;\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n color *= texture2DSRGB(material_BaseTexture, v_uv);\n #endif\n\n // Emissive\n vec3 emissiveRadiance = material_EmissiveColor;\n #ifdef MATERIAL_HAS_EMISSIVETEXTURE\n emissiveRadiance *= texture2DSRGB(material_EmissiveTexture, v_uv).rgb;\n #endif\n\n color.rgb += emissiveRadiance;\n\n gl_FragColor = color;\n}\n\n"; // eslint-disable-line
29350
29632
  var trailVs = "attribute vec4 a_PositionBirthTime; // xyz: World position, w: Birth time (used by CPU only)\nattribute vec4 a_CornerTangent; // x: Corner (-1 or 1), yzw: Tangent direction\nattribute float a_Distance; // Absolute cumulative distance (written once per point)\n\nuniform vec4 renderer_TrailParams; // x: TextureMode (0: Stretch, 1: Tile), y: TextureScaleX, z: TextureScaleY\nuniform vec2 renderer_DistanceParams; // x: HeadDistance, y: TailDistance\nuniform vec3 camera_Position;\nuniform mat4 camera_ViewMat;\nuniform mat4 camera_ProjMat;\nuniform vec2 renderer_WidthCurve[4]; // Width curve (4 keyframes max: x=time, y=value)\nuniform vec4 renderer_ColorKeys[4]; // Color gradient (x=time, yzw=rgb)\nuniform vec2 renderer_AlphaKeys[4]; // Alpha gradient (x=time, y=alpha)\nuniform vec4 renderer_CurveMaxTime; // x: colorMaxTime, y: alphaMaxTime, z: widthMaxTime\n\nvarying vec2 v_uv;\nvarying vec4 v_color;\n\n#include <particle_common>\n\nvoid main() {\n vec3 position = a_PositionBirthTime.xyz;\n float corner = a_CornerTangent.x;\n vec3 tangent = a_CornerTangent.yzw;\n\n // Distance-based relative position: 0=head(newest), 1=tail(oldest)\n float distFromHead = renderer_DistanceParams.x - a_Distance;\n float totalDist = renderer_DistanceParams.x - renderer_DistanceParams.y;\n float relativePos = totalDist > 0.0 ? distFromHead / totalDist : 0.0;\n\n // Billboard: expand perpendicular to tangent and view direction\n vec3 toCamera = normalize(camera_Position - position);\n vec3 right = cross(tangent, toCamera);\n float rightLenSq = dot(right, right);\n if (rightLenSq < 0.000001) {\n right = cross(tangent, vec3(0.0, 1.0, 0.0));\n rightLenSq = dot(right, right);\n if (rightLenSq < 0.000001) {\n right = cross(tangent, vec3(1.0, 0.0, 0.0));\n rightLenSq = dot(right, right);\n }\n }\n right = right * inversesqrt(rightLenSq);\n\n float width = evaluateParticleCurve(renderer_WidthCurve, min(relativePos, renderer_CurveMaxTime.z));\n vec3 worldPosition = position + right * width * 0.5 * corner;\n\n gl_Position = camera_ProjMat * camera_ViewMat * vec4(worldPosition, 1.0);\n\n // u = position along trail (affected by textureMode), v = corner side.\n float u = renderer_TrailParams.x == 0.0 ? relativePos : distFromHead;\n float v = corner * 0.5 + 0.5;\n v_uv = vec2(u * renderer_TrailParams.y, v * renderer_TrailParams.z);\n\n v_color = evaluateParticleGradient(renderer_ColorKeys, renderer_CurveMaxTime.x, renderer_AlphaKeys, renderer_CurveMaxTime.y, relativePos);\n}\n"; // eslint-disable-line
29351
29633
  var unlitFs = "#include <common>\n#include <uv_share>\n#include <FogFragmentDeclaration>\n\nuniform vec4 material_BaseColor;\nuniform float material_AlphaCutoff;\n\n#ifdef MATERIAL_HAS_BASETEXTURE\n uniform sampler2D material_BaseTexture;\n#endif\n\nvoid main() {\n vec4 baseColor = material_BaseColor;\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n baseColor *= texture2DSRGB(material_BaseTexture, v_uv);\n #endif\n\n #ifdef MATERIAL_IS_ALPHA_CUTOFF\n if( baseColor.a < material_AlphaCutoff ) {\n discard;\n }\n #endif\n\n gl_FragColor = baseColor;\n\n #ifndef MATERIAL_IS_TRANSPARENT\n gl_FragColor.a = 1.0;\n #endif\n\n #include <FogFragment>\n}\n"; // eslint-disable-line
@@ -32640,9 +32922,7 @@
32640
32922
  function UIUtils() {}
32641
32923
  UIUtils.renderOverlay = function renderOverlay(engine, scene, uiCanvases) {
32642
32924
  engine._macroCollection.enable(UIUtils._shouldSRGBCorrect);
32643
- var canvas = engine.canvas;
32644
- engine._hardwareRenderer;
32645
- var renderContext = engine._renderContext, batcherManager = engine._batcherManager;
32925
+ var canvas = engine.canvas, rhi = engine._hardwareRenderer, renderContext = engine._renderContext, batcherManager = engine._batcherManager;
32646
32926
  var uiRenderQueue = this._renderQueue || (this._renderQueue = new RenderQueue(RenderQueueType.Transparent));
32647
32927
  var virtualCamera = this._virtualCamera || (this._virtualCamera = new VirtualCamera());
32648
32928
  var viewport = this._viewport || (this._viewport = new Vector4(0, 0, 1, 1));
@@ -32651,10 +32931,16 @@
32651
32931
  camera.engine = engine;
32652
32932
  camera.scene = scene;
32653
32933
  renderContext.camera = camera;
32934
+ var width = canvas.width, height = canvas.height;
32654
32935
  var _virtualCamera_projectionMatrix = virtualCamera.projectionMatrix, projectE = _virtualCamera_projectionMatrix.elements;
32655
32936
  var _virtualCamera_viewMatrix = virtualCamera.viewMatrix, viewE = _virtualCamera_viewMatrix.elements;
32656
- projectE[0] = 2 / canvas.width, projectE[5] = 2 / canvas.height, projectE[10] = 0;
32657
- renderContext.setRenderTarget(null, viewport, 0);
32937
+ projectE[0] = 2 / width, projectE[5] = 2 / height, projectE[10] = 0;
32938
+ // Render to an intermediate RT with Depth24Stencil8 so that stencil-based UI Mask works.
32939
+ // The default canvas framebuffer is created without a stencil buffer
32940
+ // (see WebGLGraphicDevice._webGLOptions.stencil = false).
32941
+ var overlayRT = UIUtils._getOverlayRT(engine, width, height);
32942
+ renderContext.setRenderTarget(overlayRT, viewport, 0);
32943
+ rhi.clearRenderTarget(engine, CameraClearFlags.All, UIUtils._clearColor);
32658
32944
  for(var i = 0, n = uiCanvases.length; i < n; i++){
32659
32945
  var uiCanvas = uiCanvases.get(i);
32660
32946
  if (uiCanvas) {
@@ -32675,12 +32961,52 @@
32675
32961
  engine._renderCount++;
32676
32962
  }
32677
32963
  }
32964
+ // Blit overlay RT to default framebuffer with premultiplied alpha blending.
32965
+ // Blitter.blitTexture picks the non-flipping `blitMesh` when destination is null,
32966
+ // but the RT contents are written in standard Y-up NDC, so we flip V here via
32967
+ // sourceScaleOffset to match the default framebuffer orientation.
32968
+ Blitter.blitTexture(engine, overlayRT.getColorTexture(0), null, 0, viewport, UIUtils._getOverlayBlitMaterial(engine), 0, UIUtils._flipYScaleOffset);
32678
32969
  renderContext.camera = null;
32679
32970
  engine._macroCollection.disable(UIUtils._shouldSRGBCorrect);
32680
32971
  };
32972
+ UIUtils._getOverlayRT = function _getOverlayRT(engine, width, height) {
32973
+ var rt = UIUtils._overlayRT;
32974
+ if (!rt || rt.width !== width || rt.height !== height) {
32975
+ if (rt) {
32976
+ rt.getColorTexture(0).destroy();
32977
+ rt.destroy();
32978
+ }
32979
+ var colorTexture = new Texture2D(engine, width, height, TextureFormat.R8G8B8A8, false);
32980
+ colorTexture.isGCIgnored = true;
32981
+ rt = new RenderTarget(engine, width, height, colorTexture, TextureFormat.Depth24Stencil8);
32982
+ rt.isGCIgnored = true;
32983
+ UIUtils._overlayRT = rt;
32984
+ }
32985
+ return rt;
32986
+ };
32987
+ UIUtils._getOverlayBlitMaterial = function _getOverlayBlitMaterial(engine) {
32988
+ var material = UIUtils._overlayBlitMaterial;
32989
+ if (!material) {
32990
+ material = new Material(engine, Shader.find("blit"));
32991
+ material.isGCIgnored = true;
32992
+ var renderState = material.renderState;
32993
+ renderState.depthState.enabled = false;
32994
+ renderState.depthState.writeEnabled = false;
32995
+ var target = renderState.blendState.targetBlendState;
32996
+ target.enabled = true;
32997
+ target.sourceColorBlendFactor = BlendFactor.One;
32998
+ target.destinationColorBlendFactor = BlendFactor.OneMinusSourceAlpha;
32999
+ target.sourceAlphaBlendFactor = BlendFactor.One;
33000
+ target.destinationAlphaBlendFactor = BlendFactor.OneMinusSourceAlpha;
33001
+ UIUtils._overlayBlitMaterial = material;
33002
+ }
33003
+ return material;
33004
+ };
32681
33005
  return UIUtils;
32682
33006
  }();
32683
33007
  UIUtils._shouldSRGBCorrect = ShaderMacro.getByName("ENGINE_SHOULD_SRGB_CORRECT");
33008
+ UIUtils._clearColor = new Color(0, 0, 0, 0);
33009
+ /** Flip V so that Y-up RT content maps correctly onto the default framebuffer. */ UIUtils._flipYScaleOffset = new Vector4(1, -1, 0, 1);
32684
33010
  var OverlayCamera = function OverlayCamera() {
32685
33011
  // @ts-ignore
32686
33012
  this.instanceId = ++EngineObject._instanceIdCounter;
@@ -33505,16 +33831,44 @@
33505
33831
  this.hasStencilWritten = false;
33506
33832
  this._preMaskLayer = SpriteMaskLayer.Nothing;
33507
33833
  this._allSpriteMasks = new DisorderedArray();
33834
+ this._filteredMasksByLayer = new Map();
33835
+ this._isFilteredMasksDirty = true;
33508
33836
  }
33509
33837
  var _proto = MaskManager.prototype;
33510
33838
  _proto.addSpriteMask = function addSpriteMask(mask) {
33511
33839
  mask._maskIndex = this._allSpriteMasks.length;
33512
33840
  this._allSpriteMasks.add(mask);
33841
+ this._setFilteredMasksDirty();
33513
33842
  };
33514
33843
  _proto.removeSpriteMask = function removeSpriteMask(mask) {
33515
33844
  var replaced = this._allSpriteMasks.deleteByIndex(mask._maskIndex);
33516
33845
  replaced && (replaced._maskIndex = mask._maskIndex);
33517
33846
  mask._maskIndex = -1;
33847
+ this._setFilteredMasksDirty();
33848
+ };
33849
+ _proto.onMaskInfluenceLayersChange = function onMaskInfluenceLayersChange() {
33850
+ this._setFilteredMasksDirty();
33851
+ };
33852
+ _proto.isVisibleByMask = function isVisibleByMask(maskInteraction, maskLayer, worldPoint) {
33853
+ if (maskInteraction === SpriteMaskInteraction.None) {
33854
+ return true;
33855
+ }
33856
+ var masks = this._getMasksByLayer(maskLayer);
33857
+ var insideMask = false;
33858
+ for(var i = 0, n = masks.length; i < n; i++){
33859
+ if (masks[i]._containsWorldPoint(worldPoint)) {
33860
+ insideMask = true;
33861
+ break;
33862
+ }
33863
+ }
33864
+ switch(maskInteraction){
33865
+ case SpriteMaskInteraction.VisibleInsideMask:
33866
+ return insideMask;
33867
+ case SpriteMaskInteraction.VisibleOutsideMask:
33868
+ return !insideMask;
33869
+ default:
33870
+ return true;
33871
+ }
33518
33872
  };
33519
33873
  _proto.drawMask = function drawMask(context, pipelineStageTagValue, maskLayer) {
33520
33874
  var incrementMaskQueue = MaskManager.getMaskIncrementRenderQueue();
@@ -33571,6 +33925,34 @@
33571
33925
  var allSpriteMasks = this._allSpriteMasks;
33572
33926
  allSpriteMasks.length = 0;
33573
33927
  allSpriteMasks.garbageCollection();
33928
+ this._filteredMasksByLayer.clear();
33929
+ this._isFilteredMasksDirty = true;
33930
+ };
33931
+ _proto._setFilteredMasksDirty = function _setFilteredMasksDirty() {
33932
+ this._isFilteredMasksDirty = true;
33933
+ };
33934
+ _proto._getMasksByLayer = function _getMasksByLayer(maskLayer) {
33935
+ if (maskLayer === SpriteMaskLayer.Nothing) {
33936
+ return [];
33937
+ }
33938
+ if (this._isFilteredMasksDirty) {
33939
+ this._filteredMasksByLayer.clear();
33940
+ this._isFilteredMasksDirty = false;
33941
+ }
33942
+ var filteredMasks = this._filteredMasksByLayer.get(maskLayer);
33943
+ if (!filteredMasks) {
33944
+ filteredMasks = [];
33945
+ var allMasks = this._allSpriteMasks;
33946
+ var maskElements = allMasks._elements;
33947
+ for(var i = 0, n = allMasks.length; i < n; i++){
33948
+ var mask = maskElements[i];
33949
+ if (mask.influenceLayers & maskLayer) {
33950
+ filteredMasks.push(mask);
33951
+ }
33952
+ }
33953
+ this._filteredMasksByLayer.set(maskLayer, filteredMasks);
33954
+ }
33955
+ return filteredMasks;
33574
33956
  };
33575
33957
  _proto._buildMaskRenderElement = function _buildMaskRenderElement(curMaskLayer, incrementMaskQueue, decrementMaskQueue) {
33576
33958
  var preMaskLayer = this._preMaskLayer;
@@ -45752,6 +46134,8 @@
45752
46134
  Logger: Logger,
45753
46135
  MSAASamples: MSAASamples,
45754
46136
  MainModule: MainModule,
46137
+ MaskDirtyFlags: MaskDirtyFlags,
46138
+ MaskRenderable: MaskRenderable,
45755
46139
  Material: Material,
45756
46140
  Mesh: Mesh,
45757
46141
  MeshColliderShape: MeshColliderShape,
@@ -45811,6 +46195,7 @@
45811
46195
  ReferResource: ReferResource,
45812
46196
  RefractionMode: RefractionMode,
45813
46197
  RenderBufferDepthFormat: RenderBufferDepthFormat,
46198
+ RenderElement: RenderElement,
45814
46199
  RenderFace: RenderFace,
45815
46200
  RenderQueue: RenderQueue,
45816
46201
  RenderQueueFlags: RenderQueueFlags,
@@ -45867,6 +46252,7 @@
45867
46252
  SpriteMask: SpriteMask,
45868
46253
  SpriteMaskInteraction: SpriteMaskInteraction,
45869
46254
  SpriteMaskLayer: SpriteMaskLayer,
46255
+ SpriteMaskUtils: SpriteMaskUtils,
45870
46256
  SpriteModifyFlags: SpriteModifyFlags,
45871
46257
  SpriteRenderer: SpriteRenderer,
45872
46258
  SpriteTileMode: SpriteTileMode,
@@ -55693,7 +56079,7 @@
55693
56079
  ], EXT_texture_webp);
55694
56080
 
55695
56081
  //@ts-ignore
55696
- var version = "0.0.0-experimental-2.0-game.6";
56082
+ var version = "0.0.0-experimental-2.0-game.8";
55697
56083
  console.log("Galacean Engine Version: " + version);
55698
56084
  for(var key in CoreObjects){
55699
56085
  Loader.registerClass(key, CoreObjects[key]);
@@ -55845,6 +56231,8 @@
55845
56231
  exports.Logger = Logger;
55846
56232
  exports.MSAASamples = MSAASamples;
55847
56233
  exports.MainModule = MainModule;
56234
+ exports.MaskDirtyFlags = MaskDirtyFlags;
56235
+ exports.MaskRenderable = MaskRenderable;
55848
56236
  exports.Material = Material;
55849
56237
  exports.MaterialLoaderType = MaterialLoaderType;
55850
56238
  exports.MathUtil = MathUtil;
@@ -55918,6 +56306,7 @@
55918
56306
  exports.ReflectionParser = ReflectionParser;
55919
56307
  exports.RefractionMode = RefractionMode;
55920
56308
  exports.RenderBufferDepthFormat = RenderBufferDepthFormat;
56309
+ exports.RenderElement = RenderElement;
55921
56310
  exports.RenderFace = RenderFace;
55922
56311
  exports.RenderQueue = RenderQueue;
55923
56312
  exports.RenderQueueFlags = RenderQueueFlags;
@@ -55974,6 +56363,7 @@
55974
56363
  exports.SpriteMask = SpriteMask;
55975
56364
  exports.SpriteMaskInteraction = SpriteMaskInteraction;
55976
56365
  exports.SpriteMaskLayer = SpriteMaskLayer;
56366
+ exports.SpriteMaskUtils = SpriteMaskUtils;
55977
56367
  exports.SpriteModifyFlags = SpriteModifyFlags;
55978
56368
  exports.SpriteRenderer = SpriteRenderer;
55979
56369
  exports.SpriteTileMode = SpriteTileMode;