UNPKG

@yuebai008/cli

Version:

Command line interface for rapid qg-minigame development

1 lines 23.4 kB
import*as Common from"../../core/common/common.js";import*as i18n from"../../core/i18n/i18n.js";import*as Platform from"../../core/platform/platform.js";import layers3DViewStyles from"./layers3DView.css.js";import*as UI from"../../ui/legacy/legacy.js";import{LayerSelection,Selection,SnapshotSelection,ScrollRectSelection}from"./LayerViewHost.js";import{Events as TransformControllerEvents,TransformController}from"./TransformController.js";const UIStrings={layerInformationIsNotYet:"Layer information is not yet available.",dLayersView:"3D Layers View",cantDisplayLayers:"Can't display layers,",webglSupportIsDisabledInYour:"WebGL support is disabled in your browser.",checkSForPossibleReasons:"Check {PH1} for possible reasons.",slowScrollRects:"Slow scroll rects",paints:"Paints",resetView:"Reset View",showPaintProfiler:"Show Paint Profiler"},str_=i18n.i18n.registerUIStrings("panels/layer_viewer/Layers3DView.ts",UIStrings),i18nString=i18n.i18n.getLocalizedString.bind(void 0,str_),vertexPositionAttributes=new Map,vertexColorAttributes=new Map,textureCoordAttributes=new Map,uniformMatrixLocations=new Map,uniformSamplerLocations=new Map,imageForTexture=new Map;export class Layers3DView extends(Common.ObjectWrapper.eventMixin(UI.Widget.VBox)){failBanner;layerViewHost;transformController;canvasElement;lastSelection;layerTree;textureManager;chromeTextures;rects;snapshotLayers;shaderProgram;oldTextureScale;depthByLayerId;visibleLayers;maxDepth;scale;layerTexture;projectionMatrix;whiteTexture;gl;dimensionsForAutoscale;needsUpdate;updateScheduled;panelToolbar;showSlowScrollRectsSetting;showPaintsSetting;mouseDownX;mouseDownY;constructor(e){super(!0),this.contentElement.classList.add("layers-3d-view"),this.failBanner=new UI.Widget.VBox,this.failBanner.element.classList.add("full-widget-dimmed-banner"),UI.UIUtils.createTextChild(this.failBanner.element,i18nString(UIStrings.layerInformationIsNotYet)),this.layerViewHost=e,this.layerViewHost.registerView(this),this.transformController=new TransformController(this.contentElement),this.transformController.addEventListener(TransformControllerEvents.TransformChanged,this.update,this),this.initToolbar(),this.canvasElement=this.contentElement.createChild("canvas"),this.canvasElement.tabIndex=0,this.canvasElement.addEventListener("dblclick",this.onDoubleClick.bind(this),!1),this.canvasElement.addEventListener("mousedown",this.onMouseDown.bind(this),!1),this.canvasElement.addEventListener("mouseup",this.onMouseUp.bind(this),!1),this.canvasElement.addEventListener("mouseleave",this.onMouseMove.bind(this),!1),this.canvasElement.addEventListener("mousemove",this.onMouseMove.bind(this),!1),this.canvasElement.addEventListener("contextmenu",this.onContextMenu.bind(this),!1),UI.ARIAUtils.setLabel(this.canvasElement,i18nString(UIStrings.dLayersView)),this.lastSelection={},this.layerTree=null,this.updateScheduled=!1,this.textureManager=new LayerTextureManager(this.update.bind(this)),this.chromeTextures=[],this.rects=[],this.snapshotLayers=new Map,this.layerViewHost.setLayerSnapshotMap(this.snapshotLayers),this.layerViewHost.showInternalLayersSetting().addChangeListener(this.update,this)}setLayerTree(e){this.layerTree=e,this.layerTexture=null,delete this.oldTextureScale,this.showPaints()&&this.textureManager.setLayerTree(e),this.update()}showImageForLayer(e,t){if(!t)return this.layerTexture=null,void this.update();UI.UIUtils.loadImage(t).then((t=>{const r=t&&LayerTextureManager.createTextureForImage(this.gl||null,t);this.layerTexture=r?{layer:e,texture:r}:null,this.update()}))}onResize(){this.resizeCanvas(),this.update()}willHide(){this.textureManager.suspend()}wasShown(){this.textureManager.resume(),this.registerCSSFiles([layers3DViewStyles]),this.needsUpdate&&(this.resizeCanvas(),this.update())}updateLayerSnapshot(e){this.textureManager.layerNeedsUpdate(e)}setOutline(e,t){this.lastSelection[e]=t,this.update()}hoverObject(e){this.setOutline(OutlineType.Hovered,e)}selectObject(e){this.setOutline(OutlineType.Hovered,null),this.setOutline(OutlineType.Selected,e)}snapshotForSelection(e){if("Snapshot"===e.type()){const t=e.snapshot();return t.snapshot.addReference(),Promise.resolve(t)}if(e.layer()){const t=e.layer().snapshots()[0];if(void 0!==t)return t}return Promise.resolve(null)}initGL(e){const t=e.getContext("webgl");return t?(t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA),t.enable(t.BLEND),t.clearColor(0,0,0,0),t.enable(t.DEPTH_TEST),t):null}createShader(e,t){if(!this.gl)return;const r=this.gl.createShader(e);r&&this.shaderProgram&&(this.gl.shaderSource(r,t),this.gl.compileShader(r),this.gl.attachShader(this.shaderProgram,r))}initShaders(){if(!this.gl)return;if(this.shaderProgram=this.gl.createProgram(),!this.shaderProgram)return;this.createShader(this.gl.FRAGMENT_SHADER,FragmentShader),this.createShader(this.gl.VERTEX_SHADER,VertexShader),this.gl.linkProgram(this.shaderProgram),this.gl.useProgram(this.shaderProgram);const e=this.gl.getAttribLocation(this.shaderProgram,"aVertexPosition");this.gl.enableVertexAttribArray(e),vertexPositionAttributes.set(this.shaderProgram,e);const t=this.gl.getAttribLocation(this.shaderProgram,"aVertexColor");this.gl.enableVertexAttribArray(t),vertexColorAttributes.set(this.shaderProgram,t);const r=this.gl.getAttribLocation(this.shaderProgram,"aTextureCoord");this.gl.enableVertexAttribArray(r),textureCoordAttributes.set(this.shaderProgram,r);const i=this.gl.getUniformLocation(this.shaderProgram,"uPMatrix");uniformMatrixLocations.set(this.shaderProgram,i);const s=this.gl.getUniformLocation(this.shaderProgram,"uSampler");uniformSamplerLocations.set(this.shaderProgram,s)}resizeCanvas(){this.canvasElement.width=this.canvasElement.offsetWidth*window.devicePixelRatio,this.canvasElement.height=this.canvasElement.offsetHeight*window.devicePixelRatio}updateTransformAndConstraints(){const e=this.dimensionsForAutoscale||{width:0,height:0},t=this.layerTree?this.layerTree.viewportSize():null,r=t?t.width:e.width,i=t?t.height:e.height,s=this.canvasElement.width,a=this.canvasElement.height,o=.1*s,n=.1*a,l=(s-2*o)/r,h=(a-2*n)/i,c=Math.min(l,h),d=Math.min(r/e.width,i/e.width)/2;this.transformController.setScaleConstraints(d,10/c);const u=this.transformController.scale(),m=this.transformController.rotateX(),g=this.transformController.rotateY();this.scale=u*c;const p=Platform.NumberUtilities.clamp(this.scale,.1,1);p!==this.oldTextureScale&&(this.oldTextureScale=p,this.textureManager.setScale(p),this.dispatchEventToListeners(Events.ScaleChanged,p));const y=(new WebKitCSSMatrix).scale(u,u,u).translate(s/2,a/2,0).rotate(m,g,0).scale(c,c,c).translate(-r/2,-i/2,0);let x;for(let e=0;e<this.rects.length;++e)x=UI.Geometry.boundsForTransformedPoints(y,this.rects[e].vertices,x);x&&this.transformController.clampOffsets((o-x.maxX)/window.devicePixelRatio,(s-o-x.minX)/window.devicePixelRatio,(n-x.maxY)/window.devicePixelRatio,(a-n-x.minY)/window.devicePixelRatio);const w=this.transformController.offsetX()*window.devicePixelRatio,T=this.transformController.offsetY()*window.devicePixelRatio;this.projectionMatrix=(new WebKitCSSMatrix).translate(w,T,0).multiply(y);const f=(new WebKitCSSMatrix).scale(1,-1,-1).translate(-1,-1,0).scale(2/this.canvasElement.width,2/this.canvasElement.height,1e-6).multiply(this.projectionMatrix);if(this.shaderProgram){const e=uniformMatrixLocations.get(this.shaderProgram);this.gl&&e&&this.gl.uniformMatrix4fv(e,!1,this.arrayFromMatrix(f))}}arrayFromMatrix(e){return new Float32Array([e.m11,e.m12,e.m13,e.m14,e.m21,e.m22,e.m23,e.m24,e.m31,e.m32,e.m33,e.m34,e.m41,e.m42,e.m43,e.m44])}initWhiteTexture(){if(!this.gl)return;this.whiteTexture=this.gl.createTexture(),this.gl.bindTexture(this.gl.TEXTURE_2D,this.whiteTexture);const e=new Uint8Array([255,255,255,255]);this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,1,1,0,this.gl.RGBA,this.gl.UNSIGNED_BYTE,e)}initChromeTextures(){function e(e,t){UI.UIUtils.loadImage(t).then((t=>{this.chromeTextures[e]=t&&LayerTextureManager.createTextureForImage(this.gl||null,t)||void 0}))}e.call(this,0,"Images/chromeLeft.avif"),e.call(this,1,"Images/chromeMiddle.avif"),e.call(this,2,"Images/chromeRight.avif")}initGLIfNecessary(){return this.gl?this.gl:(this.gl=this.initGL(this.canvasElement),this.gl?(this.initShaders(),this.initWhiteTexture(),this.initChromeTextures(),this.textureManager.setContext(this.gl),this.gl):null)}calculateDepthsAndVisibility(){this.depthByLayerId=new Map;let e=0;const t=this.layerViewHost.showInternalLayersSetting().get();if(!this.layerTree)return;const r=t?this.layerTree.root():this.layerTree.contentRoot()||this.layerTree.root();if(!r)return;const i=[r];for(this.depthByLayerId.set(r.id(),0),this.visibleLayers=new Set;i.length>0;){const r=i.shift();if(!r)break;(t||r.drawsContent())&&this.visibleLayers.add(r);const s=r.children();for(let t=0;t<s.length;++t)this.depthByLayerId.set(s[t].id(),++e),i.push(s[t])}this.maxDepth=e}depthForLayer(e){return(this.depthByLayerId.get(e.id())||0)*LayerSpacing}calculateScrollRectDepth(e,t){return this.depthForLayer(e)+t*ScrollRectSpacing+1}updateDimensionsForAutoscale(e){this.dimensionsForAutoscale||(this.dimensionsForAutoscale={width:0,height:0}),this.dimensionsForAutoscale.width=Math.max(e.width(),this.dimensionsForAutoscale.width),this.dimensionsForAutoscale.height=Math.max(e.height(),this.dimensionsForAutoscale.height)}calculateLayerRect(e){if(!this.visibleLayers.has(e))return;const t=new LayerSelection(e),r=new Rectangle(t);r.setVertices(e.quad(),this.depthForLayer(e)),this.appendRect(r),this.updateDimensionsForAutoscale(e)}appendRect(e){const t=e.relatedObject,r=Selection.isEqual(this.lastSelection[OutlineType.Selected],t),i=Selection.isEqual(this.lastSelection[OutlineType.Hovered],t);if(r)e.borderColor=SelectedBorderColor;else if(i){e.borderColor=HoveredBorderColor;const t=e.fillColor||[255,255,255,1],r=HoveredImageMaskColor;e.fillColor=[t[0]*r[0]/255,t[1]*r[1]/255,t[2]*r[2]/255,t[3]*r[3]]}else e.borderColor=BorderColor;e.lineWidth=r?SelectedBorderWidth:BorderWidth,this.rects.push(e)}calculateLayerScrollRects(e){const t=e.scrollRects();for(let r=0;r<t.length;++r){const i=new ScrollRectSelection(e,r),s=new Rectangle(i);s.calculateVerticesFromRect(e,t[r].rect,this.calculateScrollRectDepth(e,r)),s.fillColor=ScrollRectBackgroundColor,this.appendRect(s)}}calculateLayerTileRects(e){const t=this.textureManager.tilesForLayer(e);for(let r=0;r<t.length;++r){const i=t[r];if(!i.texture)continue;const s=new SnapshotSelection(e,{rect:i.rect,snapshot:i.snapshot}),a=new Rectangle(s);this.snapshotLayers.has(e)||this.snapshotLayers.set(e,s),a.calculateVerticesFromRect(e,i.rect,this.depthForLayer(e)+1),a.texture=i.texture,this.appendRect(a)}}calculateRects(){if(this.rects=[],this.snapshotLayers.clear(),this.dimensionsForAutoscale={width:0,height:0},this.layerTree&&this.layerTree.forEachLayer(this.calculateLayerRect.bind(this)),this.showSlowScrollRectsSetting&&this.showSlowScrollRectsSetting.get()&&this.layerTree&&this.layerTree.forEachLayer(this.calculateLayerScrollRects.bind(this)),this.layerTexture&&this.visibleLayers.has(this.layerTexture.layer)){const e=this.layerTexture.layer,t=new LayerSelection(e),r=new Rectangle(t);r.setVertices(e.quad(),this.depthForLayer(e)),r.texture=this.layerTexture.texture,this.appendRect(r)}else this.showPaints()&&this.layerTree&&this.layerTree.forEachLayer(this.calculateLayerTileRects.bind(this))}makeColorsArray(e){let t=[];const r=[e[0]/255,e[1]/255,e[2]/255,e[3]];for(let e=0;e<4;e++)t=t.concat(r);return t}setVertexAttribute(e,t,r){const i=this.gl;if(!i)return;const s=i.createBuffer();i.bindBuffer(i.ARRAY_BUFFER,s),i.bufferData(i.ARRAY_BUFFER,new Float32Array(t),i.STATIC_DRAW),i.vertexAttribPointer(e,r,i.FLOAT,!1,0,0)}drawRectangle(e,t,r,i){const s=this.gl;if(r=r||[255,255,255,1],!this.shaderProgram)return;const a=vertexPositionAttributes.get(this.shaderProgram),o=textureCoordAttributes.get(this.shaderProgram),n=vertexColorAttributes.get(this.shaderProgram);if(void 0!==a&&this.setVertexAttribute(a,e,3),void 0!==o&&this.setVertexAttribute(o,[0,1,1,1,1,0,0,0],2),void 0!==n&&this.setVertexAttribute(n,this.makeColorsArray(r),r.length),!s)return;const l=uniformSamplerLocations.get(this.shaderProgram);i?l&&(s.activeTexture(s.TEXTURE0),s.bindTexture(s.TEXTURE_2D,i),s.uniform1i(l,0)):this.whiteTexture&&s.bindTexture(s.TEXTURE_2D,this.whiteTexture);const h=e.length/3;s.drawArrays(t,0,h)}drawTexture(e,t,r){this.gl&&this.drawRectangle(e,this.gl.TRIANGLE_FAN,r,t)}drawViewportAndChrome(){if(!this.layerTree)return;const e=this.layerTree.viewportSize();if(!e)return;const t=!Common.Settings.Settings.instance().moduleSetting("frameViewerHideChromeWindow").get()&&this.chromeTextures.length>=3&&this.chromeTextures.indexOf(void 0)<0,r=(this.maxDepth+1)*LayerSpacing,i=Math.ceil(ViewportBorderWidth*this.scale);let s=[e.width,0,r,e.width,e.height,r,0,e.height,r,0,0,r];if(!this.gl)return;if(this.gl.lineWidth(i),this.drawRectangle(s,t?this.gl.LINE_STRIP:this.gl.LINE_LOOP,ViewportBorderColor),!t)return;const a=this.layerTree.viewportSize();if(!a)return;const o=ViewportBorderWidth/2,n=a.width+2*o;if(this.chromeTextures[0]&&this.chromeTextures[2]){const e=imageForTexture.get(this.chromeTextures[0])||{naturalHeight:0,naturalWidth:0},t=e.naturalHeight,i=imageForTexture.get(this.chromeTextures[2])||{naturalHeight:0,naturalWidth:0},a=n-e.naturalWidth-i.naturalWidth;let l=-o;const h=-t;for(let e=0;e<this.chromeTextures.length;++e){const i=this.chromeTextures[e];if(!i)continue;const o=imageForTexture.get(i);if(!o)continue;const c=1===e?a:o.naturalWidth;if(c<0||l+c>n)break;s=[l,h,r,l+c,h,r,l+c,h+t,r,l,h+t,r],this.drawTexture(s,this.chromeTextures[e]),l+=c}}}drawViewRect(e){if(!this.gl)return;const t=e.vertices;e.texture?this.drawTexture(t,e.texture,e.fillColor||void 0):e.fillColor&&this.drawRectangle(t,this.gl.TRIANGLE_FAN,e.fillColor),this.gl.lineWidth(e.lineWidth),e.borderColor&&this.drawRectangle(t,this.gl.LINE_LOOP,e.borderColor)}update(){this.isShowing()?this.updateScheduled||(this.updateScheduled=!0,requestAnimationFrame((()=>requestAnimationFrame((()=>{this.updateScheduled=!1,this.innerUpdate()}))))):this.needsUpdate=!0}innerUpdate(){if(!this.layerTree||!this.layerTree.root())return void this.failBanner.show(this.contentElement);const e=this.initGLIfNecessary();if(!e)return this.failBanner.element.removeChildren(),this.failBanner.element.appendChild(this.webglDisabledBanner()),void this.failBanner.show(this.contentElement);this.failBanner.detach();const t=this.canvasElement.width,r=this.canvasElement.height;this.calculateDepthsAndVisibility(),this.calculateRects(),this.updateTransformAndConstraints(),e.viewport(0,0,t,r),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),this.rects.forEach(this.drawViewRect.bind(this)),this.drawViewportAndChrome()}webglDisabledBanner(){const e=this.contentElement.ownerDocument.createDocumentFragment();return e.createChild("div").textContent=i18nString(UIStrings.cantDisplayLayers),e.createChild("div").textContent=i18nString(UIStrings.webglSupportIsDisabledInYour),e.appendChild(i18n.i18n.getFormatLocalizedString(str_,UIStrings.checkSForPossibleReasons,{PH1:UI.XLink.XLink.create("about:gpu")})),e}selectionFromEventPoint(e){const t=e;if(!this.layerTree)return null;let r=1/0,i=null;const s=(new WebKitCSSMatrix).scale(1,-1,-1).translate(-1,-1,0).multiply(this.projectionMatrix),a=(t.clientX-this.canvasElement.getBoundingClientRect().left)*window.devicePixelRatio,o=-(t.clientY-this.canvasElement.getBoundingClientRect().top)*window.devicePixelRatio;return this.rects.forEach((function(e){if(!e.relatedObject)return;const t=e.intersectWithLine(s,a,o);t&&t<r&&(r=t,i=e.relatedObject)})),i}createVisibilitySetting(e,t,r,i){const s=Common.Settings.Settings.instance().createSetting(t,r);return s.setTitle(e),s.addChangeListener(this.update,this),i.appendToolbarItem(new UI.Toolbar.ToolbarSettingCheckbox(s)),s}initToolbar(){this.panelToolbar=this.transformController.toolbar(),this.contentElement.appendChild(this.panelToolbar.element),this.showPaintsSetting=this.createVisibilitySetting(i18nString(UIStrings.paints),"frameViewerShowPaints",!1,this.panelToolbar),this.showSlowScrollRectsSetting=this.createVisibilitySetting(i18nString(UIStrings.slowScrollRects),"frameViewerShowSlowScrollRects",!0,this.panelToolbar),this.showPaintsSetting.addChangeListener(this.updatePaints,this),Common.Settings.Settings.instance().moduleSetting("frameViewerHideChromeWindow").addChangeListener(this.update,this)}onContextMenu(e){const t=new UI.ContextMenu.ContextMenu(e);t.defaultSection().appendItem(i18nString(UIStrings.resetView),(()=>this.transformController.resetAndNotify()),!1);const r=this.selectionFromEventPoint(e);r&&"Snapshot"===r.type()&&t.defaultSection().appendItem(i18nString(UIStrings.showPaintProfiler),(()=>this.dispatchEventToListeners(Events.PaintProfilerRequested,r)),!1),this.layerViewHost.showContextMenu(t,r)}onMouseMove(e){e.which||this.layerViewHost.hoverObject(this.selectionFromEventPoint(e))}onMouseDown(e){const t=e;this.mouseDownX=t.clientX,this.mouseDownY=t.clientY}onMouseUp(e){const t=e;this.mouseDownX&&Math.abs(t.clientX-this.mouseDownX)<6&&Math.abs(t.clientY-(this.mouseDownY||0))<6&&(this.canvasElement.focus(),this.layerViewHost.selectObject(this.selectionFromEventPoint(e))),delete this.mouseDownX,delete this.mouseDownY}onDoubleClick(e){const t=this.selectionFromEventPoint(e);t&&("Snapshot"===t.type()||t.layer())&&this.dispatchEventToListeners(Events.PaintProfilerRequested,t),e.stopPropagation()}updatePaints(){this.showPaints()?(this.textureManager.setLayerTree(this.layerTree),this.textureManager.forceUpdate()):this.textureManager.reset(),this.update()}showPaints(){return!!this.showPaintsSetting&&this.showPaintsSetting.get()}}export var OutlineType;!function(e){e.Hovered="hovered",e.Selected="selected"}(OutlineType||(OutlineType={}));export var Events;!function(e){e.PaintProfilerRequested="PaintProfilerRequested",e.ScaleChanged="ScaleChanged"}(Events||(Events={}));export const FragmentShader="precision mediump float;\nvarying vec4 vColor;\nvarying vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void)\n{\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)) * vColor;\n}";export const VertexShader="attribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nattribute vec4 aVertexColor;\nuniform mat4 uPMatrix;\nvarying vec2 vTextureCoord;\nvarying vec4 vColor;\nvoid main(void)\n{\ngl_Position = uPMatrix * vec4(aVertexPosition, 1.0);\nvColor = aVertexColor;\nvTextureCoord = aTextureCoord;\n}";export const HoveredBorderColor=[0,0,255,1];export const SelectedBorderColor=[0,255,0,1];export const BorderColor=[0,0,0,1];export const ViewportBorderColor=[160,160,160,1];export const ScrollRectBackgroundColor=[178,100,100,.6];export const HoveredImageMaskColor=[200,200,255,1];export const BorderWidth=1;export const SelectedBorderWidth=2;export const ViewportBorderWidth=3;export const LayerSpacing=20;export const ScrollRectSpacing=4;export class LayerTextureManager{textureUpdatedCallback;throttler;scale;active;queue;tilesByLayer;gl;constructor(e){this.textureUpdatedCallback=e,this.throttler=new Common.Throttler.Throttler(0),this.scale=0,this.active=!1,this.reset()}static createTextureForImage(e,t){if(!e)throw new Error("WebGLRenderingContext not provided");const r=e.createTexture();if(!r)throw new Error("Unable to create texture");return imageForTexture.set(r,t),e.bindTexture(e.TEXTURE_2D,r),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,1),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindTexture(e.TEXTURE_2D,null),r}reset(){this.tilesByLayer&&this.setLayerTree(null),this.tilesByLayer=new Map,this.queue=[]}setContext(e){this.gl=e,this.scale&&this.updateTextures()}suspend(){this.active=!1}resume(){this.active=!0,this.queue.length&&this.update()}setLayerTree(e){const t=new Set,r=Array.from(this.tilesByLayer.keys());e&&e.forEachLayer((e=>{e.drawsContent()&&(t.add(e),this.tilesByLayer.has(e)||(this.tilesByLayer.set(e,[]),this.layerNeedsUpdate(e)))})),r.length||this.forceUpdate();for(const e of r){if(t.has(e))continue;const r=this.tilesByLayer.get(e);r&&r.forEach((e=>e.dispose())),this.tilesByLayer.delete(e)}}setSnapshotsForLayer(e,t){const r=new Map((this.tilesByLayer.get(e)||[]).map((e=>[e.snapshot,e]))),i=[],s=[];for(const e of t){const t=r.get(e.snapshot);t?(s.push(t),r.delete(e.snapshot)):i.push(new Tile(e))}this.tilesByLayer.set(e,s.concat(i));for(const e of r.values())e.dispose();const a=this.gl;return a&&this.scale?Promise.all(i.map((e=>e.update(a,this.scale)))).then(this.textureUpdatedCallback):Promise.resolve()}setScale(e){this.scale&&this.scale>=e||(this.scale=e,this.updateTextures())}tilesForLayer(e){return this.tilesByLayer.get(e)||[]}layerNeedsUpdate(e){this.queue.indexOf(e)<0&&this.queue.push(e),this.active&&this.throttler.schedule(this.update.bind(this))}forceUpdate(){this.queue.forEach((e=>this.updateLayer(e))),this.queue=[],this.update()}update(){const e=this.queue.shift();return e?(this.queue.length&&this.throttler.schedule(this.update.bind(this)),this.updateLayer(e)):Promise.resolve()}updateLayer(e){return Promise.all(e.snapshots()).then((t=>this.setSnapshotsForLayer(e,t.filter((e=>null!==e)))))}updateTextures(){if(this.gl&&this.scale)for(const e of this.tilesByLayer.values())for(const t of e){const e=t.updateScale(this.gl,this.scale);e&&e.then(this.textureUpdatedCallback)}}}export class Rectangle{relatedObject;lineWidth;borderColor;fillColor;texture;vertices;constructor(e){this.relatedObject=e,this.lineWidth=1,this.borderColor=null,this.fillColor=null,this.texture=null}setVertices(e,t){this.vertices=[e[0],e[1],t,e[2],e[3],t,e[4],e[5],t,e[6],e[7],t]}calculatePointOnQuad(e,t,r){const i=e[0],s=e[1],a=e[2],o=e[3],n=e[4],l=e[5],h=e[6],c=e[7],d=i+t*(a-i),u=s+t*(o-s);return[d+r*(h+t*(n-h)-d),u+r*(c+t*(l-c)-u)]}calculateVerticesFromRect(e,t,r){const i=e.quad(),s=t.x/e.width(),a=(t.x+t.width)/e.width(),o=t.y/e.height(),n=(t.y+t.height)/e.height(),l=this.calculatePointOnQuad(i,s,o).concat(this.calculatePointOnQuad(i,a,o)).concat(this.calculatePointOnQuad(i,a,n)).concat(this.calculatePointOnQuad(i,s,n));this.setVertices(l,r)}intersectWithLine(e,t,r){let i;const s=[];for(i=0;i<4;++i)s[i]=UI.Geometry.multiplyVectorByMatrixAndNormalize(new UI.Geometry.Vector(this.vertices[3*i],this.vertices[3*i+1],this.vertices[3*i+2]),e);const a=UI.Geometry.crossProduct(UI.Geometry.subtract(s[1],s[0]),UI.Geometry.subtract(s[2],s[1])),o=a.x,n=a.y,l=a.z,h=-(-(o*s[0].x+n*s[0].y+l*s[0].z)+o*t+n*r)/l,c=new UI.Geometry.Vector(t,r,h),d=s.map(UI.Geometry.subtract.bind(null,c));for(i=0;i<d.length;++i){if(UI.Geometry.scalarProduct(a,UI.Geometry.crossProduct(d[i],d[(i+1)%d.length]))<0)return}return h}}export class Tile{snapshot;rect;scale;texture;gl;constructor(e){this.snapshot=e.snapshot,this.rect=e.rect,this.scale=0,this.texture=null}dispose(){this.snapshot.release(),this.texture&&(this.gl.deleteTexture(this.texture),this.texture=null)}updateScale(e,t){return this.texture&&this.scale>=t?null:this.update(e,t)}async update(e,t){this.gl=e,this.scale=t;const r=await this.snapshot.replay(t),i=r?await UI.UIUtils.loadImage(r):null;this.texture=i?LayerTextureManager.createTextureForImage(e,i):null}}