@eva/plugin-renderer-tilemap 2.1.0-beta.11 → 2.1.0-beta.13
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.
|
@@ -627,6 +627,7 @@ var _EVA_IIFE_tilemap = function (exports, eva_js, pluginRenderer, pixi_js) {
|
|
|
627
627
|
}
|
|
628
628
|
rendererUpdate(_gameObject) {}
|
|
629
629
|
update(_frame) {
|
|
630
|
+
super.update(_frame);
|
|
630
631
|
if (this.isHidden || this.contextLost) return;
|
|
631
632
|
if (this.animationDrivers.size === 0) return;
|
|
632
633
|
this.probeBegin(TILEMAP_PROBE_NAMES.ANIM_TICK_MS);
|
|
@@ -682,7 +683,11 @@ var _EVA_IIFE_tilemap = function (exports, eva_js, pluginRenderer, pixi_js) {
|
|
|
682
683
|
if (changed.type === eva_js.OBSERVER_TYPE.ADD) {
|
|
683
684
|
yield this.handleAdd(gameObjectId, changed.gameObject, component);
|
|
684
685
|
} else if (changed.type === eva_js.OBSERVER_TYPE.CHANGE) {
|
|
685
|
-
|
|
686
|
+
if (!this.records[gameObjectId]) {
|
|
687
|
+
yield this.handleAdd(gameObjectId, changed.gameObject, component);
|
|
688
|
+
} else {
|
|
689
|
+
yield this.handleChange(gameObjectId, component, changed);
|
|
690
|
+
}
|
|
686
691
|
} else if (changed.type === eva_js.OBSERVER_TYPE.REMOVE) {
|
|
687
692
|
this.handleRemove(gameObjectId);
|
|
688
693
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var i in n)({}).hasOwnProperty.call(n,i)&&(e[i]=n[i])}return e},_extends.apply(null,arguments)}globalThis.EVA=globalThis.EVA||{},globalThis.EVA.plugin=globalThis.EVA.plugin||{},globalThis.EVA.plugin.renderer=globalThis.EVA.plugin.renderer||{};var _EVA_IIFE_tilemap=function(e,t,n,i){"use strict";function o(e,t,n,i){var o,r=arguments.length,s=r<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,n):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,i);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(s=(r<3?o(s):r>3?o(t,n,s):o(t,n))||s);return r>3&&s&&Object.defineProperty(t,n,s),s}function r(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function s(e,t,n,i){return new(n||(n=Promise))(function(o,r){function s(e){try{a(i.next(e))}catch(e){r(e)}}function l(e){try{a(i.throw(e))}catch(e){r(e)}}function a(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(s,l)}a((i=i.apply(e,t||[])).next())})}"function"==typeof SuppressedError&&SuppressedError,"function"==typeof SuppressedError&&SuppressedError;class l extends Error{constructor(){super("Symbol keys are not supported yet!"),Object.setPrototypeOf(this,new.target.prototype)}}const a="IDE_PROPERTY_METADATA";function c(e,t,n,i){let o=Reflect.getMetadata("design:type",e,t),r=o===Array;const s=function(e){return e===String?"string":e===Number?"number":e===Boolean?"boolean":"unknown"}(o);if("unknown"!==s&&(o=s),i){const e=i();Array.isArray(e)?(r=!0,o=e[0]):o=e}const l=Reflect.getMetadata(a,e.constructor)||{},c=_extends(_extends(_extends({},l[t]||{}),{type:o,isArray:r}),n);l[t]=c,Reflect.defineMetadata(a,l,e.constructor);!function(e,t,n){const i=e.constructor,o=i.IDEProps||{};o[t]=_extends(_extends({key:t},o[t]),n),i.IDEProps=o}(e,t,function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(i=Object.getOwnPropertySymbols(e);o<i.length;o++)t.indexOf(i[o])<0&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]])}return n}(c,["isArray"]))}function d(e){return t={type:e},(e,i)=>{if("symbol"==typeof i)throw new l;const{options:o,returnTypeFunc:r}=function(e,t){return"function"==typeof e?{returnTypeFunc:e,options:t||{}}:{options:e||{}}}(t,n);c(e,i,o,r)};var t,n}var u;!function(e){e[e.Edit=2]="Edit",e[e.Game=4]="Game",e[e.All=6]="All"}(u||(u={}));class h extends t.Component{constructor(){super(...arguments),this.tileset="",this.tileWidth=32,this.tileHeight=32,this.tilesetSpacing=0,this.tilesetMargin=0,this.layers=[],this.tilemapRef="",this.layersV2=void 0}init(e){e&&_extends(this,e)}}h.componentName="Tilemap",o([d("string"),r("design:type",String)],h.prototype,"tileset",void 0),o([d("number"),r("design:type",Number)],h.prototype,"tileWidth",void 0),o([d("number"),r("design:type",Number)],h.prototype,"tileHeight",void 0),o([d("number"),r("design:type",Number)],h.prototype,"tilesetSpacing",void 0),o([d("number"),r("design:type",Number)],h.prototype,"tilesetMargin",void 0),o([d("string"),r("design:type",String)],h.prototype,"tilemapRef",void 0);const f=16;function p(e){return{sourceSlot:255&e,col:e>>>8&255,row:e>>>16&255,altIdx:e>>>24&31,flipH:1==(e>>>29&1),flipV:1==(e>>>30&1),transpose:1==(e>>>31&1)}}function m(e){return!(255&e)}function y(e){const t=function(e){if("function"==typeof atob){const t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n}const t=globalThis.Buffer;if(t)return new Uint8Array(t.from(e,"base64"));const n=e.replace(/[^A-Za-z0-9+/]/g,""),i=e.endsWith("==")?2:e.endsWith("=")?1:0,o=Math.floor(3*n.length/4)-i,r=new Uint8Array(o);let s=0;for(let e=0;e<n.length;e+=4){const t=v.indexOf(n[e])<<18|v.indexOf(n[e+1])<<12|(n[e+2]?v.indexOf(n[e+2]):0)<<6|(n[e+3]?v.indexOf(n[e+3]):0);s<o&&(r[s++]=t>>16&255),s<o&&(r[s++]=t>>8&255),s<o&&(r[s++]=255&t)}return r}(e.blob);if(1024!==t.byteLength)throw new Error(`decodeChunk: expected 1024 bytes, got ${t.byteLength}`);const n=new Uint8Array(t.byteLength);return n.set(t),new Int32Array(n.buffer)}const v="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function g(e){var t,n,i,o,r,s,l,a,c,d,u,h,f,p,m,y;const v=new Map,g=[],T=new Map;for(let C=0;C<e.sources.length;C++){const b=e.sources[C];if(g.push(b),v.set(b.id,C+1),"atlas"===b.kind&&b.textureAsset){const e=T.get(b.textureAsset);if(e){const v=e.regionSize.width===b.regionSize.width&&e.regionSize.height===b.regionSize.height,g=(null!==(n=null===(t=e.margins)||void 0===t?void 0:t.x)&&void 0!==n?n:0)===(null!==(o=null===(i=b.margins)||void 0===i?void 0:i.x)&&void 0!==o?o:0)&&(null!==(s=null===(r=e.margins)||void 0===r?void 0:r.y)&&void 0!==s?s:0)===(null!==(a=null===(l=b.margins)||void 0===l?void 0:l.y)&&void 0!==a?a:0),T=(null!==(d=null===(c=e.separation)||void 0===c?void 0:c.x)&&void 0!==d?d:0)===(null!==(h=null===(u=b.separation)||void 0===u?void 0:u.x)&&void 0!==h?h:0)&&(null!==(p=null===(f=e.separation)||void 0===f?void 0:f.y)&&void 0!==p?p:0)===(null!==(y=null===(m=b.separation)||void 0===m?void 0:m.y)&&void 0!==y?y:0);v&&g&&T||"undefined"!=typeof console&&console.warn(`[Tilemap] Atlas sources '${e.sourceId}' and '${b.id}' share textureAsset='${b.textureAsset}' but differ in regionSize/margins/separation. Frame texture cache may collide and render wrong frames. Use distinct textureAssets per atlas source.`)}else T.set(b.textureAsset,{regionSize:b.regionSize,margins:b.margins,separation:b.separation,sourceId:b.id})}}return{raw:e,sourcesBySlot:g,slotByIdMap:v,tileWidth:e.tileSize.width,tileHeight:e.tileSize.height}}class T{constructor(){this.animations=[],this.lastFrameIdxByKey=new Map}loadFromTileset(e){var t;this.animations=[],this.lastFrameIdxByKey.clear();for(let n=0;n<e.sources.length;n++){const i=e.sources[n];if("atlas"!==i.kind)continue;const o=n+1;for(const e of i.tiles){const n=e.animation;if(!n||!n.frames||0===n.frames.length)continue;const i=n.frames.map(e=>{var t;return{col:e.atlasCoords.col,row:e.atlasCoords.row,durationMs:n.stepMs*(null!==(t=e.durationFactor)&&void 0!==t?t:1)}}),r=i.reduce((e,t)=>e+t.durationMs,0);if(r<=0)continue;const s="randomStart"===n.phase?C(o,e.atlasCoords.col,e.atlasCoords.row,r):0;this.animations.push({sourceSlot:o,col:e.atlasCoords.col,row:e.atlasCoords.row,frames:i,totalDurationMs:r,phase:null!==(t=n.phase)&&void 0!==t?t:"sync",phaseOffsetMs:s})}}}get animationCount(){return this.animations.length}isAnimatedSource(e,t,n){for(const i of this.animations)if(i.sourceSlot===e&&i.col===t&&i.row===n)return!0;return!1}advance(e){const t=new Map,n=new Set;for(const i of this.animations){const o=`${i.sourceSlot},${i.col},${i.row}`,r=((e+i.phaseOffsetMs)%i.totalDurationMs+i.totalDurationMs)%i.totalDurationMs;let s=0,l=0;for(;l<i.frames.length&&(s+=i.frames[l].durationMs,!(r<s));l++);l>=i.frames.length&&(l=i.frames.length-1);const a=i.frames[l];t.set(o,{col:a.col,row:a.row});this.lastFrameIdxByKey.get(o)!==l&&(n.add(o),this.lastFrameIdxByKey.set(o,l))}return{currentFrames:t,dirtyKeys:n}}reset(){this.lastFrameIdxByKey.clear()}}function C(e,t,n,i){let o=73856093*e^19349663*t^83492791*n;o=1274126177*(o^o>>>13),o^=o>>>16;const r=(o>>>0)/4294967295;return Math.floor(r*i)}const b={DIRTY_REBUILD_MS:"tilemap.dirtyRebuild.ms",CULL_CHECK_MS:"tilemap.cullCheck.ms",ANIM_TICK_MS:"tilemap.animTick.ms",DRAWCALLS_COUNT:"tilemap.drawcalls.count",DRAWCALLS_BY_ATLAS:"tilemap.drawcalls.byAtlas",PHYSICS_REBAKE_MS:"tilemap.physicsRebake.ms",GPU_UPLOAD_MS:"tilemap.gpuUpload.ms",GPU_UPLOAD_BYTES:"tilemap.gpuUpload.bytes",AUTOTILE_MS:"tilemap.autotile.ms",PATCH_APPLY_MS:"tilemap.patchApply.ms",DIRTY_PENDING:"tilemap.dirty.pending",DIRTY_FRAMES_BEHIND:"tilemap.dirty.framesBehind",BODIES_TOTAL:"tilemap.bodies.total",BODIES_CREATED:"tilemap.bodies.created",BODIES_DESTROYED:"tilemap.bodies.destroyed",STRATEGY_SPRITE_COUNT:"tilemap.strategy.sprite.count",STRATEGY_MESH_COUNT:"tilemap.strategy.mesh.count",STRATEGY_MESH_FALLBACK_COUNT:"tilemap.strategy.meshFallback.count",SCENECOLLECTION_SKIPPED_COUNT:"tilemap.sceneCollection.skipped.count",CULL_HITS_COUNT:"tilemap.cull.hits",MODE_SWITCH_FAILED_COUNT:"tilemap.modeSwitch.failed",ANIM_TICK_ERROR_COUNT:"tilemap.animTick.error.count",CONTEXT_LOST_COUNT:"tilemap.context.lost"};function x(){return"undefined"!=typeof performance&&performance.now?performance.now():0}function w(e){var t,n,i,o;const r=null==e?void 0:e.perfProbes;return r?{beginTiming:null!==(t=r.beginTiming)&&void 0!==t?t:()=>{},endTiming:null!==(n=r.endTiming)&&void 0!==n?n:()=>{},count:null!==(i=r.count)&&void 0!==i?i:()=>{},gauge:null!==(o=r.gauge)&&void 0!==o?o:()=>{},histogram:r.histogram}:null}function S(e){return e.preference&&"auto"!==e.preference?e.preference:e.atlasesInChunk>1?"sprite":e.nonEmptyCellsInChunk>=192?"mesh":"sprite"}let E=class extends n.Renderer{constructor(){super(...arguments),this.name="Tilemap",this.records={},this.animationDrivers=new Map,this.probes=null,this.isHidden=!1,this.contextLost=!1,this.canvasWithCtxListeners=null}init(){this.renderSystem=this.game.getSystem(n.RendererSystem),this.renderSystem.rendererManager.register(this),this.probes=w(this.game),this.installVisibilityHandlers()}installVisibilityHandlers(){var e,t,n;if("undefined"!=typeof document){try{this.visibilityListener=()=>{this.isHidden=!!document.hidden},document.addEventListener("visibilitychange",this.visibilityListener)}catch(e){}try{const i=null!==(n=null===(t=null===(e=this.renderSystem)||void 0===e?void 0:e.application)||void 0===t?void 0:t.canvas)&&void 0!==n?n:null;i&&"function"==typeof i.addEventListener&&(this.contextLostListener=()=>{this.contextLost=!0,this.probeCount(b.CONTEXT_LOST_COUNT,1),"undefined"!=typeof console&&console.warn("[Tilemap] WebGL context lost — pausing animation tick")},this.contextRestoredListener=()=>{this.contextLost=!1,"undefined"!=typeof console&&console.info("[Tilemap] WebGL context restored — resuming animation tick")},i.addEventListener("webglcontextlost",this.contextLostListener),i.addEventListener("webglcontextrestored",this.contextRestoredListener),this.canvasWithCtxListeners=i)}catch(e){}}}uninstallVisibilityHandlers(){if("undefined"!=typeof document&&this.visibilityListener){try{document.removeEventListener("visibilitychange",this.visibilityListener)}catch(e){}this.visibilityListener=void 0}if(this.canvasWithCtxListeners){try{this.contextLostListener&&this.canvasWithCtxListeners.removeEventListener("webglcontextlost",this.contextLostListener),this.contextRestoredListener&&this.canvasWithCtxListeners.removeEventListener("webglcontextrestored",this.contextRestoredListener)}catch(e){}this.contextLostListener=void 0,this.contextRestoredListener=void 0,this.canvasWithCtxListeners=null}}attachPerfProbes(e){this.probes=e}setCullingBoundsHint(e,t){const n=this.records[e];n&&(n.cullingBoundsHint=null===t?void 0:t)}invalidateChunks(e,t,n){const i=this.records[e];if(!i||0===n.length)return;let o=i.dirtyChunkKeys.get(t);o||(o=new Set,i.dirtyChunkKeys.set(t,o));for(const e of n)o.add(e);let r=0;for(const e of i.dirtyChunkKeys.values())r+=e.size;if(this.probeGauge(b.DIRTY_PENDING,r),!i.flushScheduled){i.flushScheduled=!0;("undefined"!=typeof requestAnimationFrame?requestAnimationFrame:e=>setTimeout(()=>e(0),16))(()=>this.flushDirtyChunks(e))}}flushDirtyChunks(e){var t,n,o,r,s,l,a,c,d,u,h,f,p,m;const y=this.records[e];if(!y)return;if(y.flushScheduled=!1,0===y.dirtyChunkKeys.size)return;if("v2"!==y.mode||!y.loadedTileset)return y.dirtyChunkKeys.clear(),void this.probeGauge(b.DIRTY_PENDING,0);this.probeCount(b.DIRTY_FRAMES_BEHIND,1);const v=y.loadedTileset,g=null!==(t=this.animationDrivers.get(e))&&void 0!==t?t:null,T=this.game;let C=null;if(null==T?void 0:T.gameObjects)for(const t of T.gameObjects){if(t.id!==e)continue;const i=null===(n=t.components)||void 0===n?void 0:n.find(e=>"Tilemap"===(null==e?void 0:e.name));if(i){C=i;break}}const x=null!==(r=null===(o=null==C?void 0:C.cellSize)||void 0===o?void 0:o.width)&&void 0!==r?r:v.tileWidth,w=null!==(l=null===(s=null==C?void 0:C.cellSize)||void 0===s?void 0:s.height)&&void 0!==l?l:v.tileHeight,S=null!==(c=null===(a=null==C?void 0:C.mapOrigin)||void 0===a?void 0:a.x)&&void 0!==c?c:0,E=null!==(u=null===(d=null==C?void 0:C.mapOrigin)||void 0===d?void 0:d.y)&&void 0!==u?u:0;this.probeBegin(b.DIRTY_REBUILD_MS);try{for(const[e,t]of y.dirtyChunkKeys){const n=y.layerContainersV2.get(e);if(!n)continue;const o=null!==(f=null===(h=null==C?void 0:C.layersV2)||void 0===h?void 0:h.find(t=>t.id===e))&&void 0!==f?f:null;if(o)for(const e of t){const t=n.chunkContainers.get(e);if(t){n.container.removeChild(t);try{t.destroy({children:!0})}catch(e){}n.chunkContainers.delete(e)}const r=null===(m=null===(p=o.cellData)||void 0===p?void 0:p.chunks)||void 0===m?void 0:m[e];if(!r||r.nonEmpty<=0)continue;const s=new i.Container;s.label=`chunk-${e}`,this.populateChunkSprites(s,e,r,y,v,x,w,S,E,o,g),n.container.addChild(s),n.chunkContainers.set(e,s)}}}finally{this.probeEnd(b.DIRTY_REBUILD_MS)}y.dirtyChunkKeys.clear(),this.probeGauge(b.DIRTY_PENDING,0),this.requestRedraw()}probeBegin(e){var t;null===(t=this.probes)||void 0===t||t.beginTiming(e)}probeEnd(e){var t;null===(t=this.probes)||void 0===t||t.endTiming(e)}probeCount(e,t=1){var n;null===(n=this.probes)||void 0===n||n.count(e,t)}probeGauge(e,t){var n;null===(n=this.probes)||void 0===n||n.gauge(e,t)}rendererUpdate(e){}update(e){if(this.isHidden||this.contextLost)return;if(0===this.animationDrivers.size)return;this.probeBegin(b.ANIM_TICK_MS);let t=0;try{const e="undefined"!=typeof performance&&performance.now?performance.now():0;for(const[n,i]of this.animationDrivers){const o=this.records[n];if(o&&"v2"===o.mode)try{const n=i.advance(e);if(0===n.dirtyKeys.size)continue;const r=o.loadedTileset;if(!r)continue;let s=!1;for(const e of n.dirtyKeys){const i=o.animatedSpritesByAnimKey.get(e);if(!i||0===i.length)continue;const l=n.currentFrames.get(e);if(!l)continue;const a=e.split(","),c=Number.parseInt(a[0],10),d=this.getAtlasFrameTexture(o,r,{sourceSlot:c,col:l.col,row:l.row});if(d)for(const e of i)e.texture=d,s=!0,t++}s&&this.requestRedraw()}catch(e){this.probeCount(b.ANIM_TICK_ERROR_COUNT,1),"undefined"!=typeof console&&console.error(`[Tilemap] animation tick failed for entity ${n}`,e)}}}finally{this.probeEnd(b.ANIM_TICK_MS),t>0&&this.probeCount("tilemap.anim.spritesSwapped",t)}}componentChanged(e){return s(this,void 0,void 0,function*(){if("Tilemap"!==e.componentName)return;const n=e.component,i=e.gameObject.id;e.type===t.OBSERVER_TYPE.ADD?yield this.handleAdd(i,e.gameObject,n):e.type===t.OBSERVER_TYPE.CHANGE?yield this.handleChange(i,n,e):e.type===t.OBSERVER_TYPE.REMOVE&&this.handleRemove(i)})}handleAdd(e,t,n){return s(this,void 0,void 0,function*(){this.probeBegin(b.DIRTY_REBUILD_MS);try{const o=this.increaseAsyncId(e),r=this.detectMode(n),s=new i.Container,l=this.containerManager.getContainer(e);l&&l.addChildAt(s,0);const a={root:s,layerContainers:[],layerContainersV2:new Map,frameTextures:[],frameTexturesV2:new Map,baseTexture:null,atlasTextures:new Map,loadedTileset:null,mode:r,animatedSpritesByAnimKey:new Map,sceneCollectionWarnedSourceIds:new Set,dirtyChunkKeys:new Map,flushScheduled:!1};this.records[e]=a,"v1"===r?yield this.ensureV1Built(a,e,t,n,o):"v2"===r&&(yield this.ensureV2Built(a,e,t,n,o))}finally{this.probeEnd(b.DIRTY_REBUILD_MS)}})}ensureV1Built(e,t,n,i,o){return s(this,void 0,void 0,function*(){const r=yield this.loadV1Texture(i);this.validateAsyncId(t,o)&&(r?(e.baseTexture=r,this.buildLayersV1(e,i),this.requestRedraw()):"undefined"!=typeof console&&console.error(`GameObject:${n.name}'s Tilemap tileset load error`))})}ensureV2Built(e,t,n,i,o){return s(this,void 0,void 0,function*(){const r=yield this.loadV2Tileset(i);if(!this.validateAsyncId(t,o))return;if(!r)return void("undefined"!=typeof console&&console.error(`GameObject:${n.name}'s Tilemap tilemapRef load error`));if(e.loadedTileset=r,yield this.loadAtlasTextures(e,r),!this.validateAsyncId(t,o))return;const s=new T;s.loadFromTileset(r.raw);const l=s.animationCount>0?s:null;l&&this.animationDrivers.set(t,l),this.buildLayersV2(e,i,l),this.requestRedraw()})}requestRedraw(){var e;try{const t=null===(e=this.renderSystem)||void 0===e?void 0:e.application;(null==t?void 0:t.renderer)&&t.stage&&t.renderer.render(t.stage)}catch(e){"undefined"!=typeof console&&console.warn("[Tilemap] requestRedraw failed",e)}}handleChange(e,t,n){var i,o;return s(this,void 0,void 0,function*(){const r=this.records[e];if(!r)return;const s=null===(o=null===(i=n.prop)||void 0===i?void 0:i.prop)||void 0===o?void 0:o[0];this.probeBegin(b.PATCH_APPLY_MS);try{const i=this.detectMode(t);if(i!==r.mode){const o=this.increaseAsyncId(e);try{if("v1"===r.mode?this.tearDownChildrenV1(r):"v2"===r.mode&&(this.tearDownChildrenV2(r),this.animationDrivers.delete(e)),r.baseTexture=null,r.loadedTileset=null,"v1"===i){const i=yield this.loadV1Texture(t);if(!this.validateAsyncId(e,o))return;if(!i)return r.mode="unknown",this.probeCount(b.MODE_SWITCH_FAILED_COUNT,1),void("undefined"!=typeof console&&console.error(`GameObject:${n.gameObject.name}'s Tilemap mode-switch v→v1 failed (tileset load returned null)`));r.mode="v1",r.baseTexture=i,this.buildLayersV1(r,t),this.requestRedraw()}else if("v2"===i){const i=yield this.loadV2Tileset(t);if(!this.validateAsyncId(e,o))return;if(!i)return r.mode="unknown",this.probeCount(b.MODE_SWITCH_FAILED_COUNT,1),void("undefined"!=typeof console&&console.error(`GameObject:${n.gameObject.name}'s Tilemap mode-switch v→v2 failed (tilemapRef load returned null)`));if(yield this.loadAtlasTextures(r,i),!this.validateAsyncId(e,o))return;r.mode="v2",r.loadedTileset=i;const s=new T;s.loadFromTileset(i.raw);const l=s.animationCount>0?s:null;l&&this.animationDrivers.set(e,l),this.buildLayersV2(r,t,l),this.requestRedraw()}else r.mode="unknown"}catch(e){r.mode="unknown",this.probeCount(b.MODE_SWITCH_FAILED_COUNT,1),"undefined"!=typeof console&&console.error("[Tilemap] mode switch threw",e)}return}if("tileset"===s&&"v1"===r.mode){const n=this.increaseAsyncId(e),i=yield this.loadV1Texture(t);if(!this.validateAsyncId(e,n))return;if(!i)return;this.tearDownChildrenV1(r),r.baseTexture=i,this.buildLayersV1(r,t),this.requestRedraw()}else if("tilemapRef"===s&&"v2"===r.mode){const n=this.increaseAsyncId(e),i=yield this.loadV2Tileset(t);if(!this.validateAsyncId(e,n))return;if(!i)return;if(this.tearDownChildrenV2(r),r.loadedTileset=i,yield this.loadAtlasTextures(r,i),!this.validateAsyncId(e,n))return;this.animationDrivers.delete(e);const o=new T;o.loadFromTileset(i.raw);const s=o.animationCount>0?o:null;s&&this.animationDrivers.set(e,s),this.buildLayersV2(r,t,s),this.requestRedraw()}else if("layersV2"===s&&"v2"===r.mode){this.tearDownChildrenV2(r),this.animationDrivers.delete(e),r.dirtyChunkKeys.clear();const n=r.loadedTileset;let i=null;if(n){const t=new T;t.loadFromTileset(n.raw),t.animationCount>0&&(i=t,this.animationDrivers.set(e,t))}this.buildLayersV2(r,t,i),this.requestRedraw()}}finally{this.probeEnd(b.PATCH_APPLY_MS)}})}handleRemove(e){var t;this.increaseAsyncId(e);const n=this.records[e];if(!n)return;this.tearDownChildrenV1(n),this.tearDownChildrenV2(n);const i=null===(t=this.containerManager)||void 0===t?void 0:t.getContainer(e);i&&i.removeChild(n.root),n.root.destroy({children:!0}),delete this.records[e],this.animationDrivers.delete(e),this.probeGauge("tilemap.records.alive",Object.keys(this.records).length)}detectMode(e){return e.tilemapRef?"v2":e.tileset?"v1":"unknown"}loadV1Texture(e){var n;return s(this,void 0,void 0,function*(){if(!e.tileset)return null;const{instance:i}=yield t.resource.getResource(e.tileset);return null!==(n=i)&&void 0!==n?n:null})}tearDownChildrenV1(e){for(const t of e.layerContainers)e.root.removeChild(t),t.destroy({children:!0});e.layerContainers=[];for(const t of e.frameTextures)try{t.destroy(!1)}catch(e){}e.frameTextures=[]}buildLayersV1(e,t){var n,o,r,s,l,a,c,d,u,h;const f=e.baseTexture;if(!f)return;const p=t.tileWidth||32,m=t.tileHeight||32,y=null!==(n=t.renderTileWidth)&&void 0!==n?n:p,v=null!==(o=t.renderTileHeight)&&void 0!==o?o:m,g=t.tilesetMargin||0,T=t.tilesetSpacing||0,C=null!==(u=null!==(c=null!==(a=null!==(s=null===(r=f.orig)||void 0===r?void 0:r.width)&&void 0!==s?s:null===(l=f.source)||void 0===l?void 0:l.width)&&void 0!==a?a:f.width)&&void 0!==c?c:null===(d=f.frame)||void 0===d?void 0:d.width)&&void 0!==u?u:0,b=C>0?Math.max(1,Math.floor((C-g+T)/(p+T))):1,x=t.tilesetColumns&&t.tilesetColumns>0?t.tilesetColumns:b,w=new Map,S=t=>{var n,o;if(t<=0)return null;const r=t-1,s=w.get(r);if(s)return s;const l=r%x,a=Math.floor(r/x),c=g+l*(p+T),d=g+a*(m+T);try{const t=null!==(o=null!==(n=f.source)&&void 0!==n?n:f.baseTexture)&&void 0!==o?o:f,s=new i.Texture({source:t,frame:new i.Rectangle(c,d,p,m)});return w.set(r,s),e.frameTextures.push(s),s}catch(e){return"undefined"!=typeof console&&console.warn("[Tilemap] Texture slice failed, falling back to base",e),f}};for(const n of t.layers||[]){const t=new i.Container;t.label=null!==(h=n.name)&&void 0!==h?h:"tilemap-layer";const o=n.offsetX||0,r=n.offsetY||0;null!=n.alpha&&(t.alpha=n.alpha),!1===n.visible&&(t.visible=!1);const s=n.data||[],l=n.tint;for(let e=0;e<s.length;e++){const n=s[e];if(n)for(let s=0;s<n.length;s++){const a=n[s];if(!a||a<=0)continue;const c=S(a);if(!c)continue;const d=new i.Sprite(c);d.x=o+s*p,d.y=r+e*m,d.width=y,d.height=v,null!=l&&(d.tint=l),t.addChild(d)}}e.root.addChild(t),e.layerContainers.push(t)}}loadV2Tileset(e){var n,i;return s(this,void 0,void 0,function*(){if(!e.tilemapRef)return null;const o=yield t.resource.getResource(e.tilemapRef);if(!o)return null;const r=null!==(n=o.instance)&&void 0!==n?n:null===(i=o.data)||void 0===i?void 0:i.json;return r&&"tileset"===r.kind?g(r):("undefined"!=typeof console&&console.error(`[Tilemap] resource '${e.tilemapRef}' is not a TileSet document`),null)})}loadAtlasTextures(e,n){return s(this,void 0,void 0,function*(){const i=new Set;for(const e of n.sourcesBySlot)"atlas"===e.kind&&e.textureAsset&&i.add(e.textureAsset);yield Promise.all(Array.from(i).map(n=>s(this,void 0,void 0,function*(){var i,o,r;try{const s=yield t.resource.getResource(n),l=null!==(r=null!==(i=null==s?void 0:s.instance)&&void 0!==i?i:null===(o=null==s?void 0:s.data)||void 0===o?void 0:o.image)&&void 0!==r?r:null;l&&e.atlasTextures.set(n,l)}catch(e){"undefined"!=typeof console&&console.warn(`[Tilemap] failed to load atlas asset '${n}'`,e)}})))})}tearDownChildrenV2(e){for(const{container:t}of e.layerContainersV2.values())e.root.removeChild(t),t.destroy({children:!0});e.layerContainersV2.clear();for(const t of e.frameTexturesV2.values())try{t.destroy(!1)}catch(e){}e.frameTexturesV2.clear(),e.animatedSpritesByAnimKey.clear()}buildLayersV2(e,t,n){var o,r,s,l,a,c,d,u,h,f,p;const m=e.loadedTileset;if(!m)return;const y=null!==(r=null===(o=t.cellSize)||void 0===o?void 0:o.width)&&void 0!==r?r:m.tileWidth,v=null!==(l=null===(s=t.cellSize)||void 0===s?void 0:s.height)&&void 0!==l?l:m.tileHeight,g=null!==(c=null===(a=t.mapOrigin)||void 0===a?void 0:a.x)&&void 0!==c?c:0,T=null!==(u=null===(d=t.mapOrigin)||void 0===d?void 0:d.y)&&void 0!==u?u:0,C=(null!==(h=t.layersV2)&&void 0!==h?h:[]).map((e,t)=>({layer:e,idx:t})).sort((e,t)=>{var n,i;return(null!==(n=e.layer.zIndex)&&void 0!==n?n:0)-(null!==(i=t.layer.zIndex)&&void 0!==i?i:0)});for(const{layer:t}of C){if(!1===t.enabled)continue;const o=new i.Container;o.label=null!==(f=t.name)&&void 0!==f?f:t.id,o.alpha=null!==(p=t.opacity)&&void 0!==p?p:1,o.visible=!1!==t.visible;const r=new Map;this.buildChunksForLayer(e,o,r,t,m,y,v,g,T,n),e.root.addChild(o),e.layerContainersV2.set(t.id,{container:o,chunkContainers:r})}}buildChunksForLayer(e,t,n,o,r,s,l,a,c,d){var u;const h=o.cellData;if(!h||!h.chunks)return;const p=Object.entries(h.chunks).filter(([,e])=>e&&e.nonEmpty>0),v=p.length,g=null!==(u=e.cullingBoundsHint)&&void 0!==u?u:null;let T=0;this.probeBegin(b.CULL_CHECK_MS);for(const[u,h]of p){if(g){const e=u.split(","),t=Number.parseInt(e[0],10),n=Number.parseInt(e[1],10),i=a+t*f*s,o=c+n*f*l,r=o+f*l;if(!(i+f*s>g.minX&&i<g.maxX&&r>g.minY&&o<g.maxY)){T++;continue}}const p=new i.Container;p.label=`chunk-${u}`;let C=1,x=null;try{x=y(h);const e=new Set;for(let t=0;t<x.length;t++){const n=x[t];if(m(n))continue;const i=255&n,o=r.sourcesBySlot[i-1];o&&"atlas"===o.kind&&e.add(i)}C=Math.max(1,e.size)}catch(e){C=1,x=null}let w="sprite";"mesh"===S({nonEmptyCellsInChunk:h.nonEmpty,atlasesInChunk:C,totalChunksVisible:v})?this.tryBuildMeshChunk(p,u,h,r,s,l,a,c,o)?w="mesh":(w="meshFallback",this.probeCount(b.STRATEGY_MESH_FALLBACK_COUNT,1),this.populateChunkSprites(p,u,h,e,r,s,l,a,c,o,d,x)):this.populateChunkSprites(p,u,h,e,r,s,l,a,c,o,d,x),"sprite"===w?this.probeCount(b.STRATEGY_SPRITE_COUNT,1):"mesh"===w&&this.probeCount(b.STRATEGY_MESH_COUNT,1),t.addChild(p),n.set(u,p)}this.probeEnd(b.CULL_CHECK_MS),T>0&&this.probeCount(b.CULL_HITS_COUNT,T)}tryBuildMeshChunk(e,t,n,i,o,r,s,l,a){return!1}populateChunkSprites(e,t,n,o,r,s,l,a,c,d,u,h){let v;if(h)v=h;else try{v=y(n)}catch(e){return void("undefined"!=typeof console&&console.warn(`[Tilemap] chunk decode failed for ${t}`,e))}const g=t.split(","),T=Number.parseInt(g[0],10),C=Number.parseInt(g[1],10),x=T*f,w=C*f,S=function(e){if(!e)return;const t=/^#?([0-9a-fA-F]{6})(?:[0-9a-fA-F]{2})?$/.exec(e);return t?parseInt(t[1],16):void 0}(d.modulate);let E=0;for(let t=0;t<f;t++)for(let n=0;n<f;n++){const d=v[t*f+n];if(m(d))continue;const h=p(d),y=this.getAtlasFrameTexture(o,r,h);if(!y)continue;const g=new i.Sprite(y);if(E++,g.x=a+(x+n)*s,g.y=c+(w+t)*l,g.width=s,g.height=l,h.flipH&&(g.scale.x=-Math.abs(g.scale.x||1)),h.flipV&&(g.scale.y=-Math.abs(g.scale.y||1)),h.transpose&&(g.rotation=Math.PI/2),h.flipH&&(g.x+=s),h.flipV&&(g.y+=l),null!=S&&(g.tint=S),e.addChild(g),u&&u.isAnimatedSource(h.sourceSlot,h.col,h.row)){const e=`${h.sourceSlot},${h.col},${h.row}`;let t=o.animatedSpritesByAnimKey.get(e);t||(t=[],o.animatedSpritesByAnimKey.set(e,t)),t.push(g)}}E>0&&this.probeCount(b.DRAWCALLS_COUNT,E)}getAtlasFrameTexture(e,t,n){var o,r,s,l;const a=t.sourcesBySlot[n.sourceSlot-1];if(!a)return null;if("atlas"!==a.kind)return"sceneCollection"===a.kind&&(this.probeCount(b.SCENECOLLECTION_SKIPPED_COUNT,1),e.sceneCollectionWarnedSourceIds.has(a.id)||(e.sceneCollectionWarnedSourceIds.add(a.id),"undefined"!=typeof console&&console.warn(`[Tilemap] sceneCollection source '${a.id}' cells are not yet rendered (prefab instantiation pending). Skipped cell at slot=${n.sourceSlot} col=${n.col} row=${n.row}.`))),null;const c=e.atlasTextures.get(a.textureAsset);if(!c)return null;const d=null!==(o=a.margins)&&void 0!==o?o:{x:0,y:0},u=null!==(r=a.separation)&&void 0!==r?r:{x:0,y:0},h=a.regionSize.width,f=a.regionSize.height,p=`${a.textureAsset}#${h}x${f}|${d.x},${d.y}|${u.x},${u.y}#${n.col},${n.row}`,m=e.frameTexturesV2.get(p);if(m)return m;const y=d.x+n.col*(h+u.x),v=d.y+n.row*(f+u.y);try{const t=null!==(l=null!==(s=c.source)&&void 0!==s?s:c.baseTexture)&&void 0!==l?l:c,n=new i.Texture({source:t,frame:new i.Rectangle(y,v,h,f)});return e.frameTexturesV2.set(p,n),n}catch(e){return"undefined"!=typeof console&&console.warn(`[Tilemap] frame slice failed for ${p}`,e),null}}destroy(){var e;for(const t in this.records){const n=parseInt(t),i=this.records[n];this.tearDownChildrenV1(i),this.tearDownChildrenV2(i);const o=null===(e=this.containerManager)||void 0===e?void 0:e.getContainer(n);o&&o.removeChild(i.root),i.root.destroy({children:!0}),delete this.records[n]}this.uninstallVisibilityHandlers()}};E.systemName="Tilemap",E=o([t.decorators.componentObserver({Tilemap:[{prop:["tileset"],deep:!1},{prop:["tilemapRef"],deep:!1},{prop:["layersV2"],deep:!1}]})],E);var _=E;const I=["topLeft","top","topRight","right","bottomRight","bottom","bottomLeft","left"];function A(e){var t;let n=0;for(let i=0;i<8;i++){n|=(15&(null!==(t=e[i])&&void 0!==t?t:15))<<4*i}return n>>>0}function R(e,t){return e>>>4*t&15}const M="#version 300 es\nprecision highp float;\n\nin vec2 aPosition;\nin vec2 aTexCoord;\nin vec4 aFlags;\n\nuniform mat3 uProjectionMatrix;\nuniform mat3 uWorldTransformMatrix;\n\nout vec2 vTexCoord;\n\nvoid main() {\n vec3 worldPos = uWorldTransformMatrix * vec3(aPosition, 1.0);\n gl_Position = vec4((uProjectionMatrix * worldPos).xy, 0.0, 1.0);\n\n vec2 uv = aTexCoord;\n if (aFlags.x > 0.5) uv.x = 1.0 - uv.x;\n if (aFlags.y > 0.5) uv.y = 1.0 - uv.y;\n if (aFlags.z > 0.5) { float t = uv.x; uv.x = uv.y; uv.y = t; }\n vTexCoord = uv;\n}\n",O="#version 300 es\nprecision highp float;\n\nin vec2 vTexCoord;\nout vec4 fragColor;\n\nuniform sampler2D uTexture;\nuniform vec4 uModulate;\n\nvoid main() {\n vec4 sampled = texture(uTexture, vTexCoord);\n fragColor = sampled * uModulate;\n if (fragColor.a < 0.01) discard;\n}\n",L={vertex:M,fragment:O},k=16;function D(e,t){const n=new Map,i=new Map;for(const t of e.sources)n.set(t.id,t);for(const e of t.sources)i.set(e.id,e);const o=[],r=[],s=[];for(const e of i.keys())n.has(e)?JSON.stringify(n.get(e))!==JSON.stringify(i.get(e))&&s.push(e):o.push(i.get(e));for(const e of n.keys())i.has(e)||r.push(e);const l=new Set,a=new Set,c=new Set,d=e=>{const t=new Map;if("atlas"!==e.kind)return t;for(const n of e.tiles)t.set(`${e.id}/${n.atlasCoords.col},${n.atlasCoords.row}`,n);return t};for(const[e,t]of i){const i=n.get(e);if(!i){const e=d(t);for(const t of e.keys())l.add(t);continue}const o=d(i),r=d(t);for(const e of r.keys())o.has(e)?JSON.stringify(o.get(e))!==JSON.stringify(r.get(e))&&c.add(e):l.add(e);for(const e of o.keys())r.has(e)||a.add(e)}for(const e of r){const t=d(n.get(e));for(const e of t.keys())a.add(e)}return{addedSources:o,removedSourceIds:r,changedSourceIds:s,addedTilesByKey:l,removedTilesByKey:a,changedTilesByKey:c}}const N=D;function B(e){return`${e.sourceSlot},${e.col},${e.row},${e.altIdx},${e.layerId}`}class V{constructor(e=1e3){this.cache=new Map,this.accessOrder=new Map,this.accessCounter=0,this.maxEntries=e}get(e){const t=B(e),n=this.cache.get(t);return n&&this.accessOrder.set(t,++this.accessCounter),n}set(e,t){const n=B(e);this.cache.set(n,t),this.accessOrder.set(n,++this.accessCounter),this.cache.size>this.maxEntries&&this.evictLRU()}has(e){return this.cache.has(B(e))}clear(){this.cache.clear(),this.accessOrder.clear(),this.accessCounter=0}get size(){return this.cache.size}evictLRU(){let e,t=1/0;for(const[n,i]of this.accessOrder)i<t&&(t=i,e=n);e&&(this.cache.delete(e),this.accessOrder.delete(e))}}function P(e,t,n){return e.map(e=>({vertices:e.vertices.map(e=>({x:e.x+t,y:e.y+n}))}))}function $(e){if(e.length<3)return[];if(!function(e){if(e.length<3)return!0;let t=0;const n=e.length;for(let i=0;i<n;i++){const o=e[i],r=e[(i+1)%n],s=e[(i+2)%n],l=r.x-o.x,a=r.y-o.y,c=s.x-r.x,d=l*(s.y-r.y)-a*c;if(0!==d)if(0===t)t=d>0?1:-1;else if((d>0?1:-1)!==t)return!1}return!0}(e)){const t=new Error(`decomposePolygon: input polygon (${e.length} vertices) is non-convex. This is a placeholder implementation that assumes convex input — concave polygons silently produce invalid Matter.js bodies. Real concave decomposition requires the 'poly-decomp' npm dependency (see ADR-0019 Phase 1). If you need concave physics tiles right now, split into convex parts manually.`);throw"undefined"!=typeof console&&console.error("[Tilemap]",t.message),t}return[{vertices:e.slice()}]}function H(e,t,n,i){return((255&e)<<24|(63&i)<<18|(511&n)<<9|511&t)>>>0}V.prototype.getNum=function(e){return this.get({sourceSlot:e>>>24&255,altIdx:e>>>18&63,row:e>>>9&511,col:511&e,layerId:"__num__"})},V.prototype.setNum=function(e,t){this.set({sourceSlot:e>>>24&255,altIdx:e>>>18&63,row:e>>>9&511,col:511&e,layerId:"__num__"},t)};const K=new class{constructor(){this.builders=new Map}register(e,t){this.builders.set(e,t)}unregister(e){this.builders.delete(e)}has(e){return this.builders.has(e)}build(e,t){const n=this.builders.get(e);return n?n(t):null}listRegisteredNames(){return Array.from(this.builders.keys())}clear(){this.builders.clear()}};function U(e){return 255&e}function F(e){return e>>>8&255}function W(e){return e>>>16&255}function Y(e){return e>>>24&31}function G(e,t){var n;const i=[];for(const[o,r]of Object.entries(e.chunksByKey)){const[s,l]=o.split(","),a=Number.parseInt(s,10),c=Number.parseInt(l,10);if(Number.isFinite(a)&&Number.isFinite(c))for(let s=0;s<16;s++)for(let l=0;l<16;l++){const d=r[16*s+l],u=U(d);if(0===u)continue;const h=F(d),f=W(d),p=Y(d),m=`${u},${h},${f},${p}`,y=e.physicsByCellKey.get(m);if(!y||0===y.length)continue;const v=e.mapOriginX+(16*a+l)*e.cellWidth+t.worldX,g=e.mapOriginY+(16*c+s)*e.cellHeight+t.worldY;for(const t of y)for(const r of t.polygons){const a=H(u,h,f,p);let c=null===(n=e.cache.getNum(a))||void 0===n?void 0:n.parts;c||(c=$(r.points),e.cache.setNum(a,{parts:c}));const d=P(c,v,g);for(let n=0;n<d.length;n++)i.push({id:`tile-${o}-${l}-${s}-${t.layerId}-${n}`,vertices:d[n].vertices,centerX:v+e.cellWidth/2,centerY:g+e.cellHeight/2,isStatic:!0,oneWay:t.oneWay,friction:t.friction,restitution:t.restitution,metadata:{layerId:t.layerId,chunkKey:o,cellLocal:[l,s]}})}}}return i}try{t.resource.registerResourceType("TILESET")}catch(e){}try{t.resource.registerInstance("TILESET",e=>{var t,n,i,o;const r=null===(t=e.data)||void 0===t?void 0:t.json,s=null===(i=null===(n=e.src)||void 0===n?void 0:n.json)||void 0===i?void 0:i.data;return null!==(o=null!=r?r:s)&&void 0!==o?o:null})}catch(e){}return e.ADR_0019_NATIVE_REGISTRY_AVAILABLE=!1,e.CHUNK_SIZE=f,e.DecompositionCache=V,e.MAX_TERRAIN_ID=14,e.NEIGHBOR_DIRECTIONS=I,e.NO_NEIGHBOR=15,e.PeeringBitIndex=class{constructor(e){this.terrainSetIndex=e,this.exact=new Map,this.wildcards=[]}add(e,t){var n;const i=[],o=[];for(let e=0;e<8;e++){const n=null==t?void 0:t[I[e]];void 0===n?(i.push(15),o.push(0)):(i.push(15&n),o.push(15))}const r=A(i),s=A(o);if(o.every(e=>15===e)){const t=null!==(n=this.exact.get(r))&&void 0!==n?n:[];t.push(e),this.exact.set(r,t)}else this.wildcards.push({key:r,mask:s,candidate:e})}match(e){const t=A(e),n=this.exact.get(t);if(n&&n.length>0)return{candidates:n.slice(),exactMatch:!0,bestHammingDistance:0};let i=1/0,o=[];for(const{key:e,mask:n,candidate:r}of this.wildcards){let s=0,l=!0;for(let o=0;o<8;o++){if(0===R(n,o))continue;if(R(t,o)!==R(e,o)&&(s++,s>i)){l=!1;break}}l&&(s<i?(i=s,o=[r]):s===i&&o.push(r))}return{candidates:o,exactMatch:!1,bestHammingDistance:i===1/0?-1:i}}get exactBucketCount(){return this.exact.size}get wildcardCount(){return this.wildcards.length}},e.TILEMAP_BODY_SOURCE_REGISTRY=K,e.TILEMAP_PROBE_NAMES=b,e.TILE_FRAG_SHADER=O,e.TILE_SHADER_SOURCES=L,e.TILE_VERT_SHADER=M,e.TileAnimationDriver=T,e.Tilemap=h,e.TilemapSystem=_,e.adaptGamePerfProbes=w,e.buildChunkGeometry=function(e){const{cells:t,chunkWorldX:n,chunkWorldY:i,cellWidth:o,cellHeight:r,atlasInfo:s}=e;if(256!==t.length)throw new Error(`buildChunkGeometry: cells length ${t.length} != 256`);let l=0;for(let e=0;e<t.length;e++)m(t[e])||l++;const a=new Float32Array(4*l*8),c=new Uint16Array(6*l);let d=0,u=0,h=0;for(let e=0;e<k;e++)for(let l=0;l<k;l++){const f=t[e*k+l];if(m(f))continue;const y=p(f),v=n+l*o,g=i+e*r,T=v+o,C=g+r,b=(s.margins.x+y.col*(s.regionWidth+s.separation.x))/s.textureWidth,x=b+s.regionWidth/s.textureWidth,w=(s.margins.y+y.row*(s.regionHeight+s.separation.y))/s.textureHeight,S=w+s.regionHeight/s.textureHeight,E=y.flipH?1:0,_=y.flipV?1:0,I=y.transpose?1:0,A=0,R=(e,t,n,i)=>{a[d++]=e,a[d++]=t,a[d++]=n,a[d++]=i,a[d++]=E,a[d++]=_,a[d++]=I,a[d++]=A};R(v,g,b,w),R(T,g,x,w),R(T,C,x,S),R(v,C,b,S);const M=4*h;c[u++]=M,c[u++]=M+1,c[u++]=M+2,c[u++]=M,c[u++]=M+2,c[u++]=M+3,h++}return{vertexData:a,indices:c,quadCount:h}},e.buildChunkMesh=function(e){const t=new i.Container;return t.label=`chunk-mesh-stub-${e.chunkKey}`,t},e.buildTileMapStaticBodies=G,e.buildTileMapStaticBodyDefinitions=function(e,t,n){var i,o;let r;null==n||n.beginTiming(b.PHYSICS_REBAKE_MS);try{r=G(e,t)}finally{null==n||n.endTiming(b.PHYSICS_REBAKE_MS)}const s=new Map;for(const e of r){const t=null!==(o=null===(i=e.metadata)||void 0===i?void 0:i.layerId)&&void 0!==o?o:"<unlabeled>";let n=s.get(t);n||(n=[],s.set(t,n)),n.push(e)}const l=r.length;return null==n||n.gauge(b.BODIES_TOTAL,l),l>0&&(null==n||n.count(b.BODIES_CREATED,l)),{bodies:r,totalBodyCount:l,bodiesByLayerId:s}},e.cacheKeyOf=B,e.cacheKeyOfNum=H,e.computeAffectedChunks=function(e,t,n){const i=new Set,o=(e,i,o)=>{const r=t.get(e);if(!r)return!1;const s=`${r}/${i},${o}`;return n.changedTilesByKey.has(s)||n.removedTilesByKey.has(s)||n.addedTilesByKey.has(s)};for(const[t,n]of Object.entries(e))for(let e=0;e<n.length;e++){const r=n[e],s=255&r;if(0===s)continue;if(o(s,r>>>8&255,r>>>16&255)){i.add(t);break}}return i},e.createInMemoryProbeRegistry=function(){const e=new Map,t=new Map,n=new Map,i=new Map;return{beginTiming(t){e.set(t,x())},endTiming(n){const i=e.get(n);if(void 0===i)return;e.delete(n);const o=x()-i;t.has(n)||t.set(n,[]),t.get(n).push(o)},count(e,t=1){var i;n.set(e,(null!==(i=n.get(e))&&void 0!==i?i:0)+t)},gauge(e,t){i.set(e,t)},histogram(e,t){this.count(`${e}.histN`),this.count(`${e}.histSum`,t)},timings:t,counts:n,gauges:i}},e.decodeChunk=y,e.decomposePolygon=$,e.diffTilesetDocuments=N,e.diffTilesetForChunkRebuild=D,e.estimateChunkMeshMemoryKB=function(e){return Math.ceil(11)},e.estimateSpriteNodes=function(e){return 1+e},e.expandSceneCollectionSource=function(e){return"sceneCollection"!==e.kind?[]:e.prefabRefs.map((t,n)=>({sourceId:e.id,prefabName:t,index:n}))},e.extractPhysicsByCellKey=function(e){const t=new Map;for(let n=0;n<e.sources.length;n++){const i=e.sources[n];if(!i||"atlas"!==i.kind||!i.tiles)continue;const o=n+1;for(const e of i.tiles){const{col:n,row:i}=e.atlasCoords;for(const r of e.alternatives){if(!r.physics||0===r.physics.length)continue;const e=`${o},${n},${i},${31&r.altId}`;t.set(e,r.physics)}}}return t},e.getRequiredTilemapProbes=function(){return Object.values(b)},e.isEmptyCellValue=m,e.isMeshPathAvailable=function(){return!1},e.makeLoadedTileset=g,e.pickAutotileCandidate=function(e,t){if(0===e.length)return null;if(1===e.length)return e[0];const n=e.reduce((e,t)=>e+(t.probability>0?t.probability:1),0),i=t()*n;let o=0;for(const t of e)if(o+=t.probability>0?t.probability:1,i<o)return t;return e[e.length-1]},e.resolveCellPrefabName=function(e,t){var n;const i=255&e;if(0===i)return null;const o=t[i-1];if(!o||"sceneCollection"!==o.kind)return null;const r=e>>>8&255;return null!==(n=o.prefabRefs[r])&&void 0!==n?n:null},e.resolveChunkRenderStrategy=S,e.translateConvexParts=P,e.unpackCell=p,Object.defineProperty(e,"__esModule",{value:!0}),e}({},EVA,EVA.plugin.renderer,PIXI);globalThis.EVA.plugin.renderer.tilemap=globalThis.EVA.plugin.renderer.tilemap||_EVA_IIFE_tilemap;
|
|
1
|
+
function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var i in n)({}).hasOwnProperty.call(n,i)&&(e[i]=n[i])}return e},_extends.apply(null,arguments)}globalThis.EVA=globalThis.EVA||{},globalThis.EVA.plugin=globalThis.EVA.plugin||{},globalThis.EVA.plugin.renderer=globalThis.EVA.plugin.renderer||{};var _EVA_IIFE_tilemap=function(e,t,n,i){"use strict";function o(e,t,n,i){var o,r=arguments.length,s=r<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,n):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,i);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(s=(r<3?o(s):r>3?o(t,n,s):o(t,n))||s);return r>3&&s&&Object.defineProperty(t,n,s),s}function r(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function s(e,t,n,i){return new(n||(n=Promise))(function(o,r){function s(e){try{a(i.next(e))}catch(e){r(e)}}function l(e){try{a(i.throw(e))}catch(e){r(e)}}function a(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(s,l)}a((i=i.apply(e,t||[])).next())})}"function"==typeof SuppressedError&&SuppressedError,"function"==typeof SuppressedError&&SuppressedError;class l extends Error{constructor(){super("Symbol keys are not supported yet!"),Object.setPrototypeOf(this,new.target.prototype)}}const a="IDE_PROPERTY_METADATA";function c(e,t,n,i){let o=Reflect.getMetadata("design:type",e,t),r=o===Array;const s=function(e){return e===String?"string":e===Number?"number":e===Boolean?"boolean":"unknown"}(o);if("unknown"!==s&&(o=s),i){const e=i();Array.isArray(e)?(r=!0,o=e[0]):o=e}const l=Reflect.getMetadata(a,e.constructor)||{},c=_extends(_extends(_extends({},l[t]||{}),{type:o,isArray:r}),n);l[t]=c,Reflect.defineMetadata(a,l,e.constructor);!function(e,t,n){const i=e.constructor,o=i.IDEProps||{};o[t]=_extends(_extends({key:t},o[t]),n),i.IDEProps=o}(e,t,function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(i=Object.getOwnPropertySymbols(e);o<i.length;o++)t.indexOf(i[o])<0&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]])}return n}(c,["isArray"]))}function d(e){return t={type:e},(e,i)=>{if("symbol"==typeof i)throw new l;const{options:o,returnTypeFunc:r}=function(e,t){return"function"==typeof e?{returnTypeFunc:e,options:t||{}}:{options:e||{}}}(t,n);c(e,i,o,r)};var t,n}var u;!function(e){e[e.Edit=2]="Edit",e[e.Game=4]="Game",e[e.All=6]="All"}(u||(u={}));class h extends t.Component{constructor(){super(...arguments),this.tileset="",this.tileWidth=32,this.tileHeight=32,this.tilesetSpacing=0,this.tilesetMargin=0,this.layers=[],this.tilemapRef="",this.layersV2=void 0}init(e){e&&_extends(this,e)}}h.componentName="Tilemap",o([d("string"),r("design:type",String)],h.prototype,"tileset",void 0),o([d("number"),r("design:type",Number)],h.prototype,"tileWidth",void 0),o([d("number"),r("design:type",Number)],h.prototype,"tileHeight",void 0),o([d("number"),r("design:type",Number)],h.prototype,"tilesetSpacing",void 0),o([d("number"),r("design:type",Number)],h.prototype,"tilesetMargin",void 0),o([d("string"),r("design:type",String)],h.prototype,"tilemapRef",void 0);const f=16;function p(e){return{sourceSlot:255&e,col:e>>>8&255,row:e>>>16&255,altIdx:e>>>24&31,flipH:1==(e>>>29&1),flipV:1==(e>>>30&1),transpose:1==(e>>>31&1)}}function m(e){return!(255&e)}function y(e){const t=function(e){if("function"==typeof atob){const t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n}const t=globalThis.Buffer;if(t)return new Uint8Array(t.from(e,"base64"));const n=e.replace(/[^A-Za-z0-9+/]/g,""),i=e.endsWith("==")?2:e.endsWith("=")?1:0,o=Math.floor(3*n.length/4)-i,r=new Uint8Array(o);let s=0;for(let e=0;e<n.length;e+=4){const t=v.indexOf(n[e])<<18|v.indexOf(n[e+1])<<12|(n[e+2]?v.indexOf(n[e+2]):0)<<6|(n[e+3]?v.indexOf(n[e+3]):0);s<o&&(r[s++]=t>>16&255),s<o&&(r[s++]=t>>8&255),s<o&&(r[s++]=255&t)}return r}(e.blob);if(1024!==t.byteLength)throw new Error(`decodeChunk: expected 1024 bytes, got ${t.byteLength}`);const n=new Uint8Array(t.byteLength);return n.set(t),new Int32Array(n.buffer)}const v="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function g(e){var t,n,i,o,r,s,l,a,c,d,u,h,f,p,m,y;const v=new Map,g=[],T=new Map;for(let C=0;C<e.sources.length;C++){const b=e.sources[C];if(g.push(b),v.set(b.id,C+1),"atlas"===b.kind&&b.textureAsset){const e=T.get(b.textureAsset);if(e){const v=e.regionSize.width===b.regionSize.width&&e.regionSize.height===b.regionSize.height,g=(null!==(n=null===(t=e.margins)||void 0===t?void 0:t.x)&&void 0!==n?n:0)===(null!==(o=null===(i=b.margins)||void 0===i?void 0:i.x)&&void 0!==o?o:0)&&(null!==(s=null===(r=e.margins)||void 0===r?void 0:r.y)&&void 0!==s?s:0)===(null!==(a=null===(l=b.margins)||void 0===l?void 0:l.y)&&void 0!==a?a:0),T=(null!==(d=null===(c=e.separation)||void 0===c?void 0:c.x)&&void 0!==d?d:0)===(null!==(h=null===(u=b.separation)||void 0===u?void 0:u.x)&&void 0!==h?h:0)&&(null!==(p=null===(f=e.separation)||void 0===f?void 0:f.y)&&void 0!==p?p:0)===(null!==(y=null===(m=b.separation)||void 0===m?void 0:m.y)&&void 0!==y?y:0);v&&g&&T||"undefined"!=typeof console&&console.warn(`[Tilemap] Atlas sources '${e.sourceId}' and '${b.id}' share textureAsset='${b.textureAsset}' but differ in regionSize/margins/separation. Frame texture cache may collide and render wrong frames. Use distinct textureAssets per atlas source.`)}else T.set(b.textureAsset,{regionSize:b.regionSize,margins:b.margins,separation:b.separation,sourceId:b.id})}}return{raw:e,sourcesBySlot:g,slotByIdMap:v,tileWidth:e.tileSize.width,tileHeight:e.tileSize.height}}class T{constructor(){this.animations=[],this.lastFrameIdxByKey=new Map}loadFromTileset(e){var t;this.animations=[],this.lastFrameIdxByKey.clear();for(let n=0;n<e.sources.length;n++){const i=e.sources[n];if("atlas"!==i.kind)continue;const o=n+1;for(const e of i.tiles){const n=e.animation;if(!n||!n.frames||0===n.frames.length)continue;const i=n.frames.map(e=>{var t;return{col:e.atlasCoords.col,row:e.atlasCoords.row,durationMs:n.stepMs*(null!==(t=e.durationFactor)&&void 0!==t?t:1)}}),r=i.reduce((e,t)=>e+t.durationMs,0);if(r<=0)continue;const s="randomStart"===n.phase?C(o,e.atlasCoords.col,e.atlasCoords.row,r):0;this.animations.push({sourceSlot:o,col:e.atlasCoords.col,row:e.atlasCoords.row,frames:i,totalDurationMs:r,phase:null!==(t=n.phase)&&void 0!==t?t:"sync",phaseOffsetMs:s})}}}get animationCount(){return this.animations.length}isAnimatedSource(e,t,n){for(const i of this.animations)if(i.sourceSlot===e&&i.col===t&&i.row===n)return!0;return!1}advance(e){const t=new Map,n=new Set;for(const i of this.animations){const o=`${i.sourceSlot},${i.col},${i.row}`,r=((e+i.phaseOffsetMs)%i.totalDurationMs+i.totalDurationMs)%i.totalDurationMs;let s=0,l=0;for(;l<i.frames.length&&(s+=i.frames[l].durationMs,!(r<s));l++);l>=i.frames.length&&(l=i.frames.length-1);const a=i.frames[l];t.set(o,{col:a.col,row:a.row});this.lastFrameIdxByKey.get(o)!==l&&(n.add(o),this.lastFrameIdxByKey.set(o,l))}return{currentFrames:t,dirtyKeys:n}}reset(){this.lastFrameIdxByKey.clear()}}function C(e,t,n,i){let o=73856093*e^19349663*t^83492791*n;o=1274126177*(o^o>>>13),o^=o>>>16;const r=(o>>>0)/4294967295;return Math.floor(r*i)}const b={DIRTY_REBUILD_MS:"tilemap.dirtyRebuild.ms",CULL_CHECK_MS:"tilemap.cullCheck.ms",ANIM_TICK_MS:"tilemap.animTick.ms",DRAWCALLS_COUNT:"tilemap.drawcalls.count",DRAWCALLS_BY_ATLAS:"tilemap.drawcalls.byAtlas",PHYSICS_REBAKE_MS:"tilemap.physicsRebake.ms",GPU_UPLOAD_MS:"tilemap.gpuUpload.ms",GPU_UPLOAD_BYTES:"tilemap.gpuUpload.bytes",AUTOTILE_MS:"tilemap.autotile.ms",PATCH_APPLY_MS:"tilemap.patchApply.ms",DIRTY_PENDING:"tilemap.dirty.pending",DIRTY_FRAMES_BEHIND:"tilemap.dirty.framesBehind",BODIES_TOTAL:"tilemap.bodies.total",BODIES_CREATED:"tilemap.bodies.created",BODIES_DESTROYED:"tilemap.bodies.destroyed",STRATEGY_SPRITE_COUNT:"tilemap.strategy.sprite.count",STRATEGY_MESH_COUNT:"tilemap.strategy.mesh.count",STRATEGY_MESH_FALLBACK_COUNT:"tilemap.strategy.meshFallback.count",SCENECOLLECTION_SKIPPED_COUNT:"tilemap.sceneCollection.skipped.count",CULL_HITS_COUNT:"tilemap.cull.hits",MODE_SWITCH_FAILED_COUNT:"tilemap.modeSwitch.failed",ANIM_TICK_ERROR_COUNT:"tilemap.animTick.error.count",CONTEXT_LOST_COUNT:"tilemap.context.lost"};function x(){return"undefined"!=typeof performance&&performance.now?performance.now():0}function w(e){var t,n,i,o;const r=null==e?void 0:e.perfProbes;return r?{beginTiming:null!==(t=r.beginTiming)&&void 0!==t?t:()=>{},endTiming:null!==(n=r.endTiming)&&void 0!==n?n:()=>{},count:null!==(i=r.count)&&void 0!==i?i:()=>{},gauge:null!==(o=r.gauge)&&void 0!==o?o:()=>{},histogram:r.histogram}:null}function S(e){return e.preference&&"auto"!==e.preference?e.preference:e.atlasesInChunk>1?"sprite":e.nonEmptyCellsInChunk>=192?"mesh":"sprite"}let E=class extends n.Renderer{constructor(){super(...arguments),this.name="Tilemap",this.records={},this.animationDrivers=new Map,this.probes=null,this.isHidden=!1,this.contextLost=!1,this.canvasWithCtxListeners=null}init(){this.renderSystem=this.game.getSystem(n.RendererSystem),this.renderSystem.rendererManager.register(this),this.probes=w(this.game),this.installVisibilityHandlers()}installVisibilityHandlers(){var e,t,n;if("undefined"!=typeof document){try{this.visibilityListener=()=>{this.isHidden=!!document.hidden},document.addEventListener("visibilitychange",this.visibilityListener)}catch(e){}try{const i=null!==(n=null===(t=null===(e=this.renderSystem)||void 0===e?void 0:e.application)||void 0===t?void 0:t.canvas)&&void 0!==n?n:null;i&&"function"==typeof i.addEventListener&&(this.contextLostListener=()=>{this.contextLost=!0,this.probeCount(b.CONTEXT_LOST_COUNT,1),"undefined"!=typeof console&&console.warn("[Tilemap] WebGL context lost — pausing animation tick")},this.contextRestoredListener=()=>{this.contextLost=!1,"undefined"!=typeof console&&console.info("[Tilemap] WebGL context restored — resuming animation tick")},i.addEventListener("webglcontextlost",this.contextLostListener),i.addEventListener("webglcontextrestored",this.contextRestoredListener),this.canvasWithCtxListeners=i)}catch(e){}}}uninstallVisibilityHandlers(){if("undefined"!=typeof document&&this.visibilityListener){try{document.removeEventListener("visibilitychange",this.visibilityListener)}catch(e){}this.visibilityListener=void 0}if(this.canvasWithCtxListeners){try{this.contextLostListener&&this.canvasWithCtxListeners.removeEventListener("webglcontextlost",this.contextLostListener),this.contextRestoredListener&&this.canvasWithCtxListeners.removeEventListener("webglcontextrestored",this.contextRestoredListener)}catch(e){}this.contextLostListener=void 0,this.contextRestoredListener=void 0,this.canvasWithCtxListeners=null}}attachPerfProbes(e){this.probes=e}setCullingBoundsHint(e,t){const n=this.records[e];n&&(n.cullingBoundsHint=null===t?void 0:t)}invalidateChunks(e,t,n){const i=this.records[e];if(!i||0===n.length)return;let o=i.dirtyChunkKeys.get(t);o||(o=new Set,i.dirtyChunkKeys.set(t,o));for(const e of n)o.add(e);let r=0;for(const e of i.dirtyChunkKeys.values())r+=e.size;if(this.probeGauge(b.DIRTY_PENDING,r),!i.flushScheduled){i.flushScheduled=!0;("undefined"!=typeof requestAnimationFrame?requestAnimationFrame:e=>setTimeout(()=>e(0),16))(()=>this.flushDirtyChunks(e))}}flushDirtyChunks(e){var t,n,o,r,s,l,a,c,d,u,h,f,p,m;const y=this.records[e];if(!y)return;if(y.flushScheduled=!1,0===y.dirtyChunkKeys.size)return;if("v2"!==y.mode||!y.loadedTileset)return y.dirtyChunkKeys.clear(),void this.probeGauge(b.DIRTY_PENDING,0);this.probeCount(b.DIRTY_FRAMES_BEHIND,1);const v=y.loadedTileset,g=null!==(t=this.animationDrivers.get(e))&&void 0!==t?t:null,T=this.game;let C=null;if(null==T?void 0:T.gameObjects)for(const t of T.gameObjects){if(t.id!==e)continue;const i=null===(n=t.components)||void 0===n?void 0:n.find(e=>"Tilemap"===(null==e?void 0:e.name));if(i){C=i;break}}const x=null!==(r=null===(o=null==C?void 0:C.cellSize)||void 0===o?void 0:o.width)&&void 0!==r?r:v.tileWidth,w=null!==(l=null===(s=null==C?void 0:C.cellSize)||void 0===s?void 0:s.height)&&void 0!==l?l:v.tileHeight,S=null!==(c=null===(a=null==C?void 0:C.mapOrigin)||void 0===a?void 0:a.x)&&void 0!==c?c:0,E=null!==(u=null===(d=null==C?void 0:C.mapOrigin)||void 0===d?void 0:d.y)&&void 0!==u?u:0;this.probeBegin(b.DIRTY_REBUILD_MS);try{for(const[e,t]of y.dirtyChunkKeys){const n=y.layerContainersV2.get(e);if(!n)continue;const o=null!==(f=null===(h=null==C?void 0:C.layersV2)||void 0===h?void 0:h.find(t=>t.id===e))&&void 0!==f?f:null;if(o)for(const e of t){const t=n.chunkContainers.get(e);if(t){n.container.removeChild(t);try{t.destroy({children:!0})}catch(e){}n.chunkContainers.delete(e)}const r=null===(m=null===(p=o.cellData)||void 0===p?void 0:p.chunks)||void 0===m?void 0:m[e];if(!r||r.nonEmpty<=0)continue;const s=new i.Container;s.label=`chunk-${e}`,this.populateChunkSprites(s,e,r,y,v,x,w,S,E,o,g),n.container.addChild(s),n.chunkContainers.set(e,s)}}}finally{this.probeEnd(b.DIRTY_REBUILD_MS)}y.dirtyChunkKeys.clear(),this.probeGauge(b.DIRTY_PENDING,0),this.requestRedraw()}probeBegin(e){var t;null===(t=this.probes)||void 0===t||t.beginTiming(e)}probeEnd(e){var t;null===(t=this.probes)||void 0===t||t.endTiming(e)}probeCount(e,t=1){var n;null===(n=this.probes)||void 0===n||n.count(e,t)}probeGauge(e,t){var n;null===(n=this.probes)||void 0===n||n.gauge(e,t)}rendererUpdate(e){}update(e){if(super.update(e),this.isHidden||this.contextLost)return;if(0===this.animationDrivers.size)return;this.probeBegin(b.ANIM_TICK_MS);let t=0;try{const e="undefined"!=typeof performance&&performance.now?performance.now():0;for(const[n,i]of this.animationDrivers){const o=this.records[n];if(o&&"v2"===o.mode)try{const n=i.advance(e);if(0===n.dirtyKeys.size)continue;const r=o.loadedTileset;if(!r)continue;let s=!1;for(const e of n.dirtyKeys){const i=o.animatedSpritesByAnimKey.get(e);if(!i||0===i.length)continue;const l=n.currentFrames.get(e);if(!l)continue;const a=e.split(","),c=Number.parseInt(a[0],10),d=this.getAtlasFrameTexture(o,r,{sourceSlot:c,col:l.col,row:l.row});if(d)for(const e of i)e.texture=d,s=!0,t++}s&&this.requestRedraw()}catch(e){this.probeCount(b.ANIM_TICK_ERROR_COUNT,1),"undefined"!=typeof console&&console.error(`[Tilemap] animation tick failed for entity ${n}`,e)}}}finally{this.probeEnd(b.ANIM_TICK_MS),t>0&&this.probeCount("tilemap.anim.spritesSwapped",t)}}componentChanged(e){return s(this,void 0,void 0,function*(){if("Tilemap"!==e.componentName)return;const n=e.component,i=e.gameObject.id;e.type===t.OBSERVER_TYPE.ADD?yield this.handleAdd(i,e.gameObject,n):e.type===t.OBSERVER_TYPE.CHANGE?this.records[i]?yield this.handleChange(i,n,e):yield this.handleAdd(i,e.gameObject,n):e.type===t.OBSERVER_TYPE.REMOVE&&this.handleRemove(i)})}handleAdd(e,t,n){return s(this,void 0,void 0,function*(){this.probeBegin(b.DIRTY_REBUILD_MS);try{const o=this.increaseAsyncId(e),r=this.detectMode(n),s=new i.Container,l=this.containerManager.getContainer(e);l&&l.addChildAt(s,0);const a={root:s,layerContainers:[],layerContainersV2:new Map,frameTextures:[],frameTexturesV2:new Map,baseTexture:null,atlasTextures:new Map,loadedTileset:null,mode:r,animatedSpritesByAnimKey:new Map,sceneCollectionWarnedSourceIds:new Set,dirtyChunkKeys:new Map,flushScheduled:!1};this.records[e]=a,"v1"===r?yield this.ensureV1Built(a,e,t,n,o):"v2"===r&&(yield this.ensureV2Built(a,e,t,n,o))}finally{this.probeEnd(b.DIRTY_REBUILD_MS)}})}ensureV1Built(e,t,n,i,o){return s(this,void 0,void 0,function*(){const r=yield this.loadV1Texture(i);this.validateAsyncId(t,o)&&(r?(e.baseTexture=r,this.buildLayersV1(e,i),this.requestRedraw()):"undefined"!=typeof console&&console.error(`GameObject:${n.name}'s Tilemap tileset load error`))})}ensureV2Built(e,t,n,i,o){return s(this,void 0,void 0,function*(){const r=yield this.loadV2Tileset(i);if(!this.validateAsyncId(t,o))return;if(!r)return void("undefined"!=typeof console&&console.error(`GameObject:${n.name}'s Tilemap tilemapRef load error`));if(e.loadedTileset=r,yield this.loadAtlasTextures(e,r),!this.validateAsyncId(t,o))return;const s=new T;s.loadFromTileset(r.raw);const l=s.animationCount>0?s:null;l&&this.animationDrivers.set(t,l),this.buildLayersV2(e,i,l),this.requestRedraw()})}requestRedraw(){var e;try{const t=null===(e=this.renderSystem)||void 0===e?void 0:e.application;(null==t?void 0:t.renderer)&&t.stage&&t.renderer.render(t.stage)}catch(e){"undefined"!=typeof console&&console.warn("[Tilemap] requestRedraw failed",e)}}handleChange(e,t,n){var i,o;return s(this,void 0,void 0,function*(){const r=this.records[e];if(!r)return;const s=null===(o=null===(i=n.prop)||void 0===i?void 0:i.prop)||void 0===o?void 0:o[0];this.probeBegin(b.PATCH_APPLY_MS);try{const i=this.detectMode(t);if(i!==r.mode){const o=this.increaseAsyncId(e);try{if("v1"===r.mode?this.tearDownChildrenV1(r):"v2"===r.mode&&(this.tearDownChildrenV2(r),this.animationDrivers.delete(e)),r.baseTexture=null,r.loadedTileset=null,"v1"===i){const i=yield this.loadV1Texture(t);if(!this.validateAsyncId(e,o))return;if(!i)return r.mode="unknown",this.probeCount(b.MODE_SWITCH_FAILED_COUNT,1),void("undefined"!=typeof console&&console.error(`GameObject:${n.gameObject.name}'s Tilemap mode-switch v→v1 failed (tileset load returned null)`));r.mode="v1",r.baseTexture=i,this.buildLayersV1(r,t),this.requestRedraw()}else if("v2"===i){const i=yield this.loadV2Tileset(t);if(!this.validateAsyncId(e,o))return;if(!i)return r.mode="unknown",this.probeCount(b.MODE_SWITCH_FAILED_COUNT,1),void("undefined"!=typeof console&&console.error(`GameObject:${n.gameObject.name}'s Tilemap mode-switch v→v2 failed (tilemapRef load returned null)`));if(yield this.loadAtlasTextures(r,i),!this.validateAsyncId(e,o))return;r.mode="v2",r.loadedTileset=i;const s=new T;s.loadFromTileset(i.raw);const l=s.animationCount>0?s:null;l&&this.animationDrivers.set(e,l),this.buildLayersV2(r,t,l),this.requestRedraw()}else r.mode="unknown"}catch(e){r.mode="unknown",this.probeCount(b.MODE_SWITCH_FAILED_COUNT,1),"undefined"!=typeof console&&console.error("[Tilemap] mode switch threw",e)}return}if("tileset"===s&&"v1"===r.mode){const n=this.increaseAsyncId(e),i=yield this.loadV1Texture(t);if(!this.validateAsyncId(e,n))return;if(!i)return;this.tearDownChildrenV1(r),r.baseTexture=i,this.buildLayersV1(r,t),this.requestRedraw()}else if("tilemapRef"===s&&"v2"===r.mode){const n=this.increaseAsyncId(e),i=yield this.loadV2Tileset(t);if(!this.validateAsyncId(e,n))return;if(!i)return;if(this.tearDownChildrenV2(r),r.loadedTileset=i,yield this.loadAtlasTextures(r,i),!this.validateAsyncId(e,n))return;this.animationDrivers.delete(e);const o=new T;o.loadFromTileset(i.raw);const s=o.animationCount>0?o:null;s&&this.animationDrivers.set(e,s),this.buildLayersV2(r,t,s),this.requestRedraw()}else if("layersV2"===s&&"v2"===r.mode){this.tearDownChildrenV2(r),this.animationDrivers.delete(e),r.dirtyChunkKeys.clear();const n=r.loadedTileset;let i=null;if(n){const t=new T;t.loadFromTileset(n.raw),t.animationCount>0&&(i=t,this.animationDrivers.set(e,t))}this.buildLayersV2(r,t,i),this.requestRedraw()}}finally{this.probeEnd(b.PATCH_APPLY_MS)}})}handleRemove(e){var t;this.increaseAsyncId(e);const n=this.records[e];if(!n)return;this.tearDownChildrenV1(n),this.tearDownChildrenV2(n);const i=null===(t=this.containerManager)||void 0===t?void 0:t.getContainer(e);i&&i.removeChild(n.root),n.root.destroy({children:!0}),delete this.records[e],this.animationDrivers.delete(e),this.probeGauge("tilemap.records.alive",Object.keys(this.records).length)}detectMode(e){return e.tilemapRef?"v2":e.tileset?"v1":"unknown"}loadV1Texture(e){var n;return s(this,void 0,void 0,function*(){if(!e.tileset)return null;const{instance:i}=yield t.resource.getResource(e.tileset);return null!==(n=i)&&void 0!==n?n:null})}tearDownChildrenV1(e){for(const t of e.layerContainers)e.root.removeChild(t),t.destroy({children:!0});e.layerContainers=[];for(const t of e.frameTextures)try{t.destroy(!1)}catch(e){}e.frameTextures=[]}buildLayersV1(e,t){var n,o,r,s,l,a,c,d,u,h;const f=e.baseTexture;if(!f)return;const p=t.tileWidth||32,m=t.tileHeight||32,y=null!==(n=t.renderTileWidth)&&void 0!==n?n:p,v=null!==(o=t.renderTileHeight)&&void 0!==o?o:m,g=t.tilesetMargin||0,T=t.tilesetSpacing||0,C=null!==(u=null!==(c=null!==(a=null!==(s=null===(r=f.orig)||void 0===r?void 0:r.width)&&void 0!==s?s:null===(l=f.source)||void 0===l?void 0:l.width)&&void 0!==a?a:f.width)&&void 0!==c?c:null===(d=f.frame)||void 0===d?void 0:d.width)&&void 0!==u?u:0,b=C>0?Math.max(1,Math.floor((C-g+T)/(p+T))):1,x=t.tilesetColumns&&t.tilesetColumns>0?t.tilesetColumns:b,w=new Map,S=t=>{var n,o;if(t<=0)return null;const r=t-1,s=w.get(r);if(s)return s;const l=r%x,a=Math.floor(r/x),c=g+l*(p+T),d=g+a*(m+T);try{const t=null!==(o=null!==(n=f.source)&&void 0!==n?n:f.baseTexture)&&void 0!==o?o:f,s=new i.Texture({source:t,frame:new i.Rectangle(c,d,p,m)});return w.set(r,s),e.frameTextures.push(s),s}catch(e){return"undefined"!=typeof console&&console.warn("[Tilemap] Texture slice failed, falling back to base",e),f}};for(const n of t.layers||[]){const t=new i.Container;t.label=null!==(h=n.name)&&void 0!==h?h:"tilemap-layer";const o=n.offsetX||0,r=n.offsetY||0;null!=n.alpha&&(t.alpha=n.alpha),!1===n.visible&&(t.visible=!1);const s=n.data||[],l=n.tint;for(let e=0;e<s.length;e++){const n=s[e];if(n)for(let s=0;s<n.length;s++){const a=n[s];if(!a||a<=0)continue;const c=S(a);if(!c)continue;const d=new i.Sprite(c);d.x=o+s*p,d.y=r+e*m,d.width=y,d.height=v,null!=l&&(d.tint=l),t.addChild(d)}}e.root.addChild(t),e.layerContainers.push(t)}}loadV2Tileset(e){var n,i;return s(this,void 0,void 0,function*(){if(!e.tilemapRef)return null;const o=yield t.resource.getResource(e.tilemapRef);if(!o)return null;const r=null!==(n=o.instance)&&void 0!==n?n:null===(i=o.data)||void 0===i?void 0:i.json;return r&&"tileset"===r.kind?g(r):("undefined"!=typeof console&&console.error(`[Tilemap] resource '${e.tilemapRef}' is not a TileSet document`),null)})}loadAtlasTextures(e,n){return s(this,void 0,void 0,function*(){const i=new Set;for(const e of n.sourcesBySlot)"atlas"===e.kind&&e.textureAsset&&i.add(e.textureAsset);yield Promise.all(Array.from(i).map(n=>s(this,void 0,void 0,function*(){var i,o,r;try{const s=yield t.resource.getResource(n),l=null!==(r=null!==(i=null==s?void 0:s.instance)&&void 0!==i?i:null===(o=null==s?void 0:s.data)||void 0===o?void 0:o.image)&&void 0!==r?r:null;l&&e.atlasTextures.set(n,l)}catch(e){"undefined"!=typeof console&&console.warn(`[Tilemap] failed to load atlas asset '${n}'`,e)}})))})}tearDownChildrenV2(e){for(const{container:t}of e.layerContainersV2.values())e.root.removeChild(t),t.destroy({children:!0});e.layerContainersV2.clear();for(const t of e.frameTexturesV2.values())try{t.destroy(!1)}catch(e){}e.frameTexturesV2.clear(),e.animatedSpritesByAnimKey.clear()}buildLayersV2(e,t,n){var o,r,s,l,a,c,d,u,h,f,p;const m=e.loadedTileset;if(!m)return;const y=null!==(r=null===(o=t.cellSize)||void 0===o?void 0:o.width)&&void 0!==r?r:m.tileWidth,v=null!==(l=null===(s=t.cellSize)||void 0===s?void 0:s.height)&&void 0!==l?l:m.tileHeight,g=null!==(c=null===(a=t.mapOrigin)||void 0===a?void 0:a.x)&&void 0!==c?c:0,T=null!==(u=null===(d=t.mapOrigin)||void 0===d?void 0:d.y)&&void 0!==u?u:0,C=(null!==(h=t.layersV2)&&void 0!==h?h:[]).map((e,t)=>({layer:e,idx:t})).sort((e,t)=>{var n,i;return(null!==(n=e.layer.zIndex)&&void 0!==n?n:0)-(null!==(i=t.layer.zIndex)&&void 0!==i?i:0)});for(const{layer:t}of C){if(!1===t.enabled)continue;const o=new i.Container;o.label=null!==(f=t.name)&&void 0!==f?f:t.id,o.alpha=null!==(p=t.opacity)&&void 0!==p?p:1,o.visible=!1!==t.visible;const r=new Map;this.buildChunksForLayer(e,o,r,t,m,y,v,g,T,n),e.root.addChild(o),e.layerContainersV2.set(t.id,{container:o,chunkContainers:r})}}buildChunksForLayer(e,t,n,o,r,s,l,a,c,d){var u;const h=o.cellData;if(!h||!h.chunks)return;const p=Object.entries(h.chunks).filter(([,e])=>e&&e.nonEmpty>0),v=p.length,g=null!==(u=e.cullingBoundsHint)&&void 0!==u?u:null;let T=0;this.probeBegin(b.CULL_CHECK_MS);for(const[u,h]of p){if(g){const e=u.split(","),t=Number.parseInt(e[0],10),n=Number.parseInt(e[1],10),i=a+t*f*s,o=c+n*f*l,r=o+f*l;if(!(i+f*s>g.minX&&i<g.maxX&&r>g.minY&&o<g.maxY)){T++;continue}}const p=new i.Container;p.label=`chunk-${u}`;let C=1,x=null;try{x=y(h);const e=new Set;for(let t=0;t<x.length;t++){const n=x[t];if(m(n))continue;const i=255&n,o=r.sourcesBySlot[i-1];o&&"atlas"===o.kind&&e.add(i)}C=Math.max(1,e.size)}catch(e){C=1,x=null}let w="sprite";"mesh"===S({nonEmptyCellsInChunk:h.nonEmpty,atlasesInChunk:C,totalChunksVisible:v})?this.tryBuildMeshChunk(p,u,h,r,s,l,a,c,o)?w="mesh":(w="meshFallback",this.probeCount(b.STRATEGY_MESH_FALLBACK_COUNT,1),this.populateChunkSprites(p,u,h,e,r,s,l,a,c,o,d,x)):this.populateChunkSprites(p,u,h,e,r,s,l,a,c,o,d,x),"sprite"===w?this.probeCount(b.STRATEGY_SPRITE_COUNT,1):"mesh"===w&&this.probeCount(b.STRATEGY_MESH_COUNT,1),t.addChild(p),n.set(u,p)}this.probeEnd(b.CULL_CHECK_MS),T>0&&this.probeCount(b.CULL_HITS_COUNT,T)}tryBuildMeshChunk(e,t,n,i,o,r,s,l,a){return!1}populateChunkSprites(e,t,n,o,r,s,l,a,c,d,u,h){let v;if(h)v=h;else try{v=y(n)}catch(e){return void("undefined"!=typeof console&&console.warn(`[Tilemap] chunk decode failed for ${t}`,e))}const g=t.split(","),T=Number.parseInt(g[0],10),C=Number.parseInt(g[1],10),x=T*f,w=C*f,S=function(e){if(!e)return;const t=/^#?([0-9a-fA-F]{6})(?:[0-9a-fA-F]{2})?$/.exec(e);return t?parseInt(t[1],16):void 0}(d.modulate);let E=0;for(let t=0;t<f;t++)for(let n=0;n<f;n++){const d=v[t*f+n];if(m(d))continue;const h=p(d),y=this.getAtlasFrameTexture(o,r,h);if(!y)continue;const g=new i.Sprite(y);if(E++,g.x=a+(x+n)*s,g.y=c+(w+t)*l,g.width=s,g.height=l,h.flipH&&(g.scale.x=-Math.abs(g.scale.x||1)),h.flipV&&(g.scale.y=-Math.abs(g.scale.y||1)),h.transpose&&(g.rotation=Math.PI/2),h.flipH&&(g.x+=s),h.flipV&&(g.y+=l),null!=S&&(g.tint=S),e.addChild(g),u&&u.isAnimatedSource(h.sourceSlot,h.col,h.row)){const e=`${h.sourceSlot},${h.col},${h.row}`;let t=o.animatedSpritesByAnimKey.get(e);t||(t=[],o.animatedSpritesByAnimKey.set(e,t)),t.push(g)}}E>0&&this.probeCount(b.DRAWCALLS_COUNT,E)}getAtlasFrameTexture(e,t,n){var o,r,s,l;const a=t.sourcesBySlot[n.sourceSlot-1];if(!a)return null;if("atlas"!==a.kind)return"sceneCollection"===a.kind&&(this.probeCount(b.SCENECOLLECTION_SKIPPED_COUNT,1),e.sceneCollectionWarnedSourceIds.has(a.id)||(e.sceneCollectionWarnedSourceIds.add(a.id),"undefined"!=typeof console&&console.warn(`[Tilemap] sceneCollection source '${a.id}' cells are not yet rendered (prefab instantiation pending). Skipped cell at slot=${n.sourceSlot} col=${n.col} row=${n.row}.`))),null;const c=e.atlasTextures.get(a.textureAsset);if(!c)return null;const d=null!==(o=a.margins)&&void 0!==o?o:{x:0,y:0},u=null!==(r=a.separation)&&void 0!==r?r:{x:0,y:0},h=a.regionSize.width,f=a.regionSize.height,p=`${a.textureAsset}#${h}x${f}|${d.x},${d.y}|${u.x},${u.y}#${n.col},${n.row}`,m=e.frameTexturesV2.get(p);if(m)return m;const y=d.x+n.col*(h+u.x),v=d.y+n.row*(f+u.y);try{const t=null!==(l=null!==(s=c.source)&&void 0!==s?s:c.baseTexture)&&void 0!==l?l:c,n=new i.Texture({source:t,frame:new i.Rectangle(y,v,h,f)});return e.frameTexturesV2.set(p,n),n}catch(e){return"undefined"!=typeof console&&console.warn(`[Tilemap] frame slice failed for ${p}`,e),null}}destroy(){var e;for(const t in this.records){const n=parseInt(t),i=this.records[n];this.tearDownChildrenV1(i),this.tearDownChildrenV2(i);const o=null===(e=this.containerManager)||void 0===e?void 0:e.getContainer(n);o&&o.removeChild(i.root),i.root.destroy({children:!0}),delete this.records[n]}this.uninstallVisibilityHandlers()}};E.systemName="Tilemap",E=o([t.decorators.componentObserver({Tilemap:[{prop:["tileset"],deep:!1},{prop:["tilemapRef"],deep:!1},{prop:["layersV2"],deep:!1}]})],E);var _=E;const I=["topLeft","top","topRight","right","bottomRight","bottom","bottomLeft","left"];function A(e){var t;let n=0;for(let i=0;i<8;i++){n|=(15&(null!==(t=e[i])&&void 0!==t?t:15))<<4*i}return n>>>0}function R(e,t){return e>>>4*t&15}const M="#version 300 es\nprecision highp float;\n\nin vec2 aPosition;\nin vec2 aTexCoord;\nin vec4 aFlags;\n\nuniform mat3 uProjectionMatrix;\nuniform mat3 uWorldTransformMatrix;\n\nout vec2 vTexCoord;\n\nvoid main() {\n vec3 worldPos = uWorldTransformMatrix * vec3(aPosition, 1.0);\n gl_Position = vec4((uProjectionMatrix * worldPos).xy, 0.0, 1.0);\n\n vec2 uv = aTexCoord;\n if (aFlags.x > 0.5) uv.x = 1.0 - uv.x;\n if (aFlags.y > 0.5) uv.y = 1.0 - uv.y;\n if (aFlags.z > 0.5) { float t = uv.x; uv.x = uv.y; uv.y = t; }\n vTexCoord = uv;\n}\n",O="#version 300 es\nprecision highp float;\n\nin vec2 vTexCoord;\nout vec4 fragColor;\n\nuniform sampler2D uTexture;\nuniform vec4 uModulate;\n\nvoid main() {\n vec4 sampled = texture(uTexture, vTexCoord);\n fragColor = sampled * uModulate;\n if (fragColor.a < 0.01) discard;\n}\n",L={vertex:M,fragment:O},k=16;function D(e,t){const n=new Map,i=new Map;for(const t of e.sources)n.set(t.id,t);for(const e of t.sources)i.set(e.id,e);const o=[],r=[],s=[];for(const e of i.keys())n.has(e)?JSON.stringify(n.get(e))!==JSON.stringify(i.get(e))&&s.push(e):o.push(i.get(e));for(const e of n.keys())i.has(e)||r.push(e);const l=new Set,a=new Set,c=new Set,d=e=>{const t=new Map;if("atlas"!==e.kind)return t;for(const n of e.tiles)t.set(`${e.id}/${n.atlasCoords.col},${n.atlasCoords.row}`,n);return t};for(const[e,t]of i){const i=n.get(e);if(!i){const e=d(t);for(const t of e.keys())l.add(t);continue}const o=d(i),r=d(t);for(const e of r.keys())o.has(e)?JSON.stringify(o.get(e))!==JSON.stringify(r.get(e))&&c.add(e):l.add(e);for(const e of o.keys())r.has(e)||a.add(e)}for(const e of r){const t=d(n.get(e));for(const e of t.keys())a.add(e)}return{addedSources:o,removedSourceIds:r,changedSourceIds:s,addedTilesByKey:l,removedTilesByKey:a,changedTilesByKey:c}}const N=D;function B(e){return`${e.sourceSlot},${e.col},${e.row},${e.altIdx},${e.layerId}`}class V{constructor(e=1e3){this.cache=new Map,this.accessOrder=new Map,this.accessCounter=0,this.maxEntries=e}get(e){const t=B(e),n=this.cache.get(t);return n&&this.accessOrder.set(t,++this.accessCounter),n}set(e,t){const n=B(e);this.cache.set(n,t),this.accessOrder.set(n,++this.accessCounter),this.cache.size>this.maxEntries&&this.evictLRU()}has(e){return this.cache.has(B(e))}clear(){this.cache.clear(),this.accessOrder.clear(),this.accessCounter=0}get size(){return this.cache.size}evictLRU(){let e,t=1/0;for(const[n,i]of this.accessOrder)i<t&&(t=i,e=n);e&&(this.cache.delete(e),this.accessOrder.delete(e))}}function P(e,t,n){return e.map(e=>({vertices:e.vertices.map(e=>({x:e.x+t,y:e.y+n}))}))}function $(e){if(e.length<3)return[];if(!function(e){if(e.length<3)return!0;let t=0;const n=e.length;for(let i=0;i<n;i++){const o=e[i],r=e[(i+1)%n],s=e[(i+2)%n],l=r.x-o.x,a=r.y-o.y,c=s.x-r.x,d=l*(s.y-r.y)-a*c;if(0!==d)if(0===t)t=d>0?1:-1;else if((d>0?1:-1)!==t)return!1}return!0}(e)){const t=new Error(`decomposePolygon: input polygon (${e.length} vertices) is non-convex. This is a placeholder implementation that assumes convex input — concave polygons silently produce invalid Matter.js bodies. Real concave decomposition requires the 'poly-decomp' npm dependency (see ADR-0019 Phase 1). If you need concave physics tiles right now, split into convex parts manually.`);throw"undefined"!=typeof console&&console.error("[Tilemap]",t.message),t}return[{vertices:e.slice()}]}function H(e,t,n,i){return((255&e)<<24|(63&i)<<18|(511&n)<<9|511&t)>>>0}V.prototype.getNum=function(e){return this.get({sourceSlot:e>>>24&255,altIdx:e>>>18&63,row:e>>>9&511,col:511&e,layerId:"__num__"})},V.prototype.setNum=function(e,t){this.set({sourceSlot:e>>>24&255,altIdx:e>>>18&63,row:e>>>9&511,col:511&e,layerId:"__num__"},t)};const K=new class{constructor(){this.builders=new Map}register(e,t){this.builders.set(e,t)}unregister(e){this.builders.delete(e)}has(e){return this.builders.has(e)}build(e,t){const n=this.builders.get(e);return n?n(t):null}listRegisteredNames(){return Array.from(this.builders.keys())}clear(){this.builders.clear()}};function U(e){return 255&e}function F(e){return e>>>8&255}function W(e){return e>>>16&255}function Y(e){return e>>>24&31}function j(e,t){var n;const i=[];for(const[o,r]of Object.entries(e.chunksByKey)){const[s,l]=o.split(","),a=Number.parseInt(s,10),c=Number.parseInt(l,10);if(Number.isFinite(a)&&Number.isFinite(c))for(let s=0;s<16;s++)for(let l=0;l<16;l++){const d=r[16*s+l],u=U(d);if(0===u)continue;const h=F(d),f=W(d),p=Y(d),m=`${u},${h},${f},${p}`,y=e.physicsByCellKey.get(m);if(!y||0===y.length)continue;const v=e.mapOriginX+(16*a+l)*e.cellWidth+t.worldX,g=e.mapOriginY+(16*c+s)*e.cellHeight+t.worldY;for(const t of y)for(const r of t.polygons){const a=H(u,h,f,p);let c=null===(n=e.cache.getNum(a))||void 0===n?void 0:n.parts;c||(c=$(r.points),e.cache.setNum(a,{parts:c}));const d=P(c,v,g);for(let n=0;n<d.length;n++)i.push({id:`tile-${o}-${l}-${s}-${t.layerId}-${n}`,vertices:d[n].vertices,centerX:v+e.cellWidth/2,centerY:g+e.cellHeight/2,isStatic:!0,oneWay:t.oneWay,friction:t.friction,restitution:t.restitution,metadata:{layerId:t.layerId,chunkKey:o,cellLocal:[l,s]}})}}}return i}try{t.resource.registerResourceType("TILESET")}catch(e){}try{t.resource.registerInstance("TILESET",e=>{var t,n,i,o;const r=null===(t=e.data)||void 0===t?void 0:t.json,s=null===(i=null===(n=e.src)||void 0===n?void 0:n.json)||void 0===i?void 0:i.data;return null!==(o=null!=r?r:s)&&void 0!==o?o:null})}catch(e){}return e.ADR_0019_NATIVE_REGISTRY_AVAILABLE=!1,e.CHUNK_SIZE=f,e.DecompositionCache=V,e.MAX_TERRAIN_ID=14,e.NEIGHBOR_DIRECTIONS=I,e.NO_NEIGHBOR=15,e.PeeringBitIndex=class{constructor(e){this.terrainSetIndex=e,this.exact=new Map,this.wildcards=[]}add(e,t){var n;const i=[],o=[];for(let e=0;e<8;e++){const n=null==t?void 0:t[I[e]];void 0===n?(i.push(15),o.push(0)):(i.push(15&n),o.push(15))}const r=A(i),s=A(o);if(o.every(e=>15===e)){const t=null!==(n=this.exact.get(r))&&void 0!==n?n:[];t.push(e),this.exact.set(r,t)}else this.wildcards.push({key:r,mask:s,candidate:e})}match(e){const t=A(e),n=this.exact.get(t);if(n&&n.length>0)return{candidates:n.slice(),exactMatch:!0,bestHammingDistance:0};let i=1/0,o=[];for(const{key:e,mask:n,candidate:r}of this.wildcards){let s=0,l=!0;for(let o=0;o<8;o++){if(0===R(n,o))continue;if(R(t,o)!==R(e,o)&&(s++,s>i)){l=!1;break}}l&&(s<i?(i=s,o=[r]):s===i&&o.push(r))}return{candidates:o,exactMatch:!1,bestHammingDistance:i===1/0?-1:i}}get exactBucketCount(){return this.exact.size}get wildcardCount(){return this.wildcards.length}},e.TILEMAP_BODY_SOURCE_REGISTRY=K,e.TILEMAP_PROBE_NAMES=b,e.TILE_FRAG_SHADER=O,e.TILE_SHADER_SOURCES=L,e.TILE_VERT_SHADER=M,e.TileAnimationDriver=T,e.Tilemap=h,e.TilemapSystem=_,e.adaptGamePerfProbes=w,e.buildChunkGeometry=function(e){const{cells:t,chunkWorldX:n,chunkWorldY:i,cellWidth:o,cellHeight:r,atlasInfo:s}=e;if(256!==t.length)throw new Error(`buildChunkGeometry: cells length ${t.length} != 256`);let l=0;for(let e=0;e<t.length;e++)m(t[e])||l++;const a=new Float32Array(4*l*8),c=new Uint16Array(6*l);let d=0,u=0,h=0;for(let e=0;e<k;e++)for(let l=0;l<k;l++){const f=t[e*k+l];if(m(f))continue;const y=p(f),v=n+l*o,g=i+e*r,T=v+o,C=g+r,b=(s.margins.x+y.col*(s.regionWidth+s.separation.x))/s.textureWidth,x=b+s.regionWidth/s.textureWidth,w=(s.margins.y+y.row*(s.regionHeight+s.separation.y))/s.textureHeight,S=w+s.regionHeight/s.textureHeight,E=y.flipH?1:0,_=y.flipV?1:0,I=y.transpose?1:0,A=0,R=(e,t,n,i)=>{a[d++]=e,a[d++]=t,a[d++]=n,a[d++]=i,a[d++]=E,a[d++]=_,a[d++]=I,a[d++]=A};R(v,g,b,w),R(T,g,x,w),R(T,C,x,S),R(v,C,b,S);const M=4*h;c[u++]=M,c[u++]=M+1,c[u++]=M+2,c[u++]=M,c[u++]=M+2,c[u++]=M+3,h++}return{vertexData:a,indices:c,quadCount:h}},e.buildChunkMesh=function(e){const t=new i.Container;return t.label=`chunk-mesh-stub-${e.chunkKey}`,t},e.buildTileMapStaticBodies=j,e.buildTileMapStaticBodyDefinitions=function(e,t,n){var i,o;let r;null==n||n.beginTiming(b.PHYSICS_REBAKE_MS);try{r=j(e,t)}finally{null==n||n.endTiming(b.PHYSICS_REBAKE_MS)}const s=new Map;for(const e of r){const t=null!==(o=null===(i=e.metadata)||void 0===i?void 0:i.layerId)&&void 0!==o?o:"<unlabeled>";let n=s.get(t);n||(n=[],s.set(t,n)),n.push(e)}const l=r.length;return null==n||n.gauge(b.BODIES_TOTAL,l),l>0&&(null==n||n.count(b.BODIES_CREATED,l)),{bodies:r,totalBodyCount:l,bodiesByLayerId:s}},e.cacheKeyOf=B,e.cacheKeyOfNum=H,e.computeAffectedChunks=function(e,t,n){const i=new Set,o=(e,i,o)=>{const r=t.get(e);if(!r)return!1;const s=`${r}/${i},${o}`;return n.changedTilesByKey.has(s)||n.removedTilesByKey.has(s)||n.addedTilesByKey.has(s)};for(const[t,n]of Object.entries(e))for(let e=0;e<n.length;e++){const r=n[e],s=255&r;if(0===s)continue;if(o(s,r>>>8&255,r>>>16&255)){i.add(t);break}}return i},e.createInMemoryProbeRegistry=function(){const e=new Map,t=new Map,n=new Map,i=new Map;return{beginTiming(t){e.set(t,x())},endTiming(n){const i=e.get(n);if(void 0===i)return;e.delete(n);const o=x()-i;t.has(n)||t.set(n,[]),t.get(n).push(o)},count(e,t=1){var i;n.set(e,(null!==(i=n.get(e))&&void 0!==i?i:0)+t)},gauge(e,t){i.set(e,t)},histogram(e,t){this.count(`${e}.histN`),this.count(`${e}.histSum`,t)},timings:t,counts:n,gauges:i}},e.decodeChunk=y,e.decomposePolygon=$,e.diffTilesetDocuments=N,e.diffTilesetForChunkRebuild=D,e.estimateChunkMeshMemoryKB=function(e){return Math.ceil(11)},e.estimateSpriteNodes=function(e){return 1+e},e.expandSceneCollectionSource=function(e){return"sceneCollection"!==e.kind?[]:e.prefabRefs.map((t,n)=>({sourceId:e.id,prefabName:t,index:n}))},e.extractPhysicsByCellKey=function(e){const t=new Map;for(let n=0;n<e.sources.length;n++){const i=e.sources[n];if(!i||"atlas"!==i.kind||!i.tiles)continue;const o=n+1;for(const e of i.tiles){const{col:n,row:i}=e.atlasCoords;for(const r of e.alternatives){if(!r.physics||0===r.physics.length)continue;const e=`${o},${n},${i},${31&r.altId}`;t.set(e,r.physics)}}}return t},e.getRequiredTilemapProbes=function(){return Object.values(b)},e.isEmptyCellValue=m,e.isMeshPathAvailable=function(){return!1},e.makeLoadedTileset=g,e.pickAutotileCandidate=function(e,t){if(0===e.length)return null;if(1===e.length)return e[0];const n=e.reduce((e,t)=>e+(t.probability>0?t.probability:1),0),i=t()*n;let o=0;for(const t of e)if(o+=t.probability>0?t.probability:1,i<o)return t;return e[e.length-1]},e.resolveCellPrefabName=function(e,t){var n;const i=255&e;if(0===i)return null;const o=t[i-1];if(!o||"sceneCollection"!==o.kind)return null;const r=e>>>8&255;return null!==(n=o.prefabRefs[r])&&void 0!==n?n:null},e.resolveChunkRenderStrategy=S,e.translateConvexParts=P,e.unpackCell=p,Object.defineProperty(e,"__esModule",{value:!0}),e}({},EVA,EVA.plugin.renderer,PIXI);globalThis.EVA.plugin.renderer.tilemap=globalThis.EVA.plugin.renderer.tilemap||_EVA_IIFE_tilemap;
|
|
@@ -775,13 +775,14 @@ let TilemapSystem = class TilemapSystem extends pluginRenderer.Renderer {
|
|
|
775
775
|
// chunkContainer,destroy + 重新调 populateChunkSprites。需要拿到 layer 配置(cellData/modulate
|
|
776
776
|
// /opacity)— 通过遍历 record.layerContainersV2 找到 chunkContainers 即可。但要 populate 还需
|
|
777
777
|
// cellData.chunks[chunkKey] — 必须找 component。
|
|
778
|
-
const game = this
|
|
778
|
+
const game = this
|
|
779
|
+
.game;
|
|
779
780
|
let component = null;
|
|
780
781
|
if (game === null || game === void 0 ? void 0 : game.gameObjects) {
|
|
781
782
|
for (const go of game.gameObjects) {
|
|
782
783
|
if (go.id !== gameObjectId)
|
|
783
784
|
continue;
|
|
784
|
-
const c = (_b = go.components) === null || _b === void 0 ? void 0 : _b.find(
|
|
785
|
+
const c = (_b = go.components) === null || _b === void 0 ? void 0 : _b.find(cc => (cc === null || cc === void 0 ? void 0 : cc.name) === 'Tilemap');
|
|
785
786
|
if (c) {
|
|
786
787
|
component = c;
|
|
787
788
|
break;
|
|
@@ -799,7 +800,7 @@ let TilemapSystem = class TilemapSystem extends pluginRenderer.Renderer {
|
|
|
799
800
|
if (!layerEntry)
|
|
800
801
|
continue;
|
|
801
802
|
// 找 layer 配置(modulate/opacity/cellData)— 必须从 component.layersV2 找。
|
|
802
|
-
const layerSpec = (_m = (_l = component === null || component === void 0 ? void 0 : component.layersV2) === null || _l === void 0 ? void 0 : _l.find(
|
|
803
|
+
const layerSpec = (_m = (_l = component === null || component === void 0 ? void 0 : component.layersV2) === null || _l === void 0 ? void 0 : _l.find(l => l.id === layerId)) !== null && _m !== void 0 ? _m : null;
|
|
803
804
|
if (!layerSpec)
|
|
804
805
|
continue;
|
|
805
806
|
for (const chunkKey of chunkKeys) {
|
|
@@ -869,6 +870,12 @@ let TilemapSystem = class TilemapSystem extends pluginRenderer.Renderer {
|
|
|
869
870
|
* 期间渲染调用堆栈抛错。
|
|
870
871
|
*/
|
|
871
872
|
update(_frame) {
|
|
873
|
+
// Renderer.update owns ComponentObserver flushing. Tilemap also needs a
|
|
874
|
+
// per-frame animation tick, but overriding update without delegating to
|
|
875
|
+
// the base class strands every ADD/CHANGE/REMOVE event in the queue and
|
|
876
|
+
// leaves the scene component permanently disconnected from its record.
|
|
877
|
+
// Lifecycle changes must still flush while animation work is paused.
|
|
878
|
+
super.update(_frame);
|
|
872
879
|
// T-N2:tab 切换到后台 / WebGL context 异常 → 暂停 tick。
|
|
873
880
|
if (this.isHidden || this.contextLost)
|
|
874
881
|
return;
|
|
@@ -877,7 +884,7 @@ let TilemapSystem = class TilemapSystem extends pluginRenderer.Renderer {
|
|
|
877
884
|
this.probeBegin(TILEMAP_PROBE_NAMES.ANIM_TICK_MS);
|
|
878
885
|
let totalSpritesSwapped = 0;
|
|
879
886
|
try {
|
|
880
|
-
const now =
|
|
887
|
+
const now = typeof performance !== 'undefined' && performance.now ? performance.now() : 0;
|
|
881
888
|
// PERF-T-O2 (see ADR-0022): consider flattening dirty (sprite, texture) pairs into a typed
|
|
882
889
|
// array once per record when animatedSpritesByAnimKey changes. Trigger: >1000 animated cells
|
|
883
890
|
// + p99(animTick.ms) > 2ms. Defer until probe data warrants.
|
|
@@ -947,7 +954,16 @@ let TilemapSystem = class TilemapSystem extends pluginRenderer.Renderer {
|
|
|
947
954
|
yield this.handleAdd(gameObjectId, changed.gameObject, component);
|
|
948
955
|
}
|
|
949
956
|
else if (changed.type === eva_js.OBSERVER_TYPE.CHANGE) {
|
|
950
|
-
|
|
957
|
+
// Editor initial reconciliation can coalesce an unflushed ADD/REMOVE pair
|
|
958
|
+
// and leave only CHANGE events for the live replacement component. A
|
|
959
|
+
// renderer must recover from that observer sequence or the live component
|
|
960
|
+
// remains disconnected from its runtime record.
|
|
961
|
+
if (!this.records[gameObjectId]) {
|
|
962
|
+
yield this.handleAdd(gameObjectId, changed.gameObject, component);
|
|
963
|
+
}
|
|
964
|
+
else {
|
|
965
|
+
yield this.handleChange(gameObjectId, component, changed);
|
|
966
|
+
}
|
|
951
967
|
}
|
|
952
968
|
else if (changed.type === eva_js.OBSERVER_TYPE.REMOVE) {
|
|
953
969
|
this.handleRemove(gameObjectId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@eva/eva.js"),t=require("@eva/inspector-decorator"),n=require("@eva/plugin-renderer"),i=require("pixi.js");function o(e,t,n,i){var o,s=arguments.length,r=s<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,n):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,n,i);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(r=(s<3?o(r):s>3?o(t,n,r):o(t,n))||r);return s>3&&r&&Object.defineProperty(t,n,r),r}function s(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function r(e,t,n,i){return new(n||(n=Promise))(function(o,s){function r(e){try{a(i.next(e))}catch(e){s(e)}}function l(e){try{a(i.throw(e))}catch(e){s(e)}}function a(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(r,l)}a((i=i.apply(e,t||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;class l extends e.Component{constructor(){super(...arguments),this.tileset="",this.tileWidth=32,this.tileHeight=32,this.tilesetSpacing=0,this.tilesetMargin=0,this.layers=[],this.tilemapRef="",this.layersV2=void 0}init(e){e&&Object.assign(this,e)}}l.componentName="Tilemap",o([t.type("string"),s("design:type",String)],l.prototype,"tileset",void 0),o([t.type("number"),s("design:type",Number)],l.prototype,"tileWidth",void 0),o([t.type("number"),s("design:type",Number)],l.prototype,"tileHeight",void 0),o([t.type("number"),s("design:type",Number)],l.prototype,"tilesetSpacing",void 0),o([t.type("number"),s("design:type",Number)],l.prototype,"tilesetMargin",void 0),o([t.type("string"),s("design:type",String)],l.prototype,"tilemapRef",void 0);const a=16;function c(e){return{sourceSlot:255&e,col:e>>>8&255,row:e>>>16&255,altIdx:e>>>24&31,flipH:1==(e>>>29&1),flipV:1==(e>>>30&1),transpose:1==(e>>>31&1)}}function d(e){return!(255&e)}function u(e){const t=function(e){if("function"==typeof atob){const t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n}const t=globalThis.Buffer;if(t)return new Uint8Array(t.from(e,"base64"));const n=e.replace(/[^A-Za-z0-9+/]/g,""),i=e.endsWith("==")?2:e.endsWith("=")?1:0,o=Math.floor(3*n.length/4)-i,s=new Uint8Array(o);let r=0;for(let e=0;e<n.length;e+=4){const t=h.indexOf(n[e])<<18|h.indexOf(n[e+1])<<12|(n[e+2]?h.indexOf(n[e+2]):0)<<6|(n[e+3]?h.indexOf(n[e+3]):0);r<o&&(s[r++]=t>>16&255),r<o&&(s[r++]=t>>8&255),r<o&&(s[r++]=255&t)}return s}(e.blob);if(1024!==t.byteLength)throw new Error(`decodeChunk: expected 1024 bytes, got ${t.byteLength}`);const n=new Uint8Array(t.byteLength);return n.set(t),new Int32Array(n.buffer)}const h="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function f(e){var t,n,i,o,s,r,l,a,c,d,u,h,f,p,m,y;const v=new Map,g=[],C=new Map;for(let T=0;T<e.sources.length;T++){const x=e.sources[T];if(g.push(x),v.set(x.id,T+1),"atlas"===x.kind&&x.textureAsset){const e=C.get(x.textureAsset);if(e){const v=e.regionSize.width===x.regionSize.width&&e.regionSize.height===x.regionSize.height,g=(null!==(n=null===(t=e.margins)||void 0===t?void 0:t.x)&&void 0!==n?n:0)===(null!==(o=null===(i=x.margins)||void 0===i?void 0:i.x)&&void 0!==o?o:0)&&(null!==(r=null===(s=e.margins)||void 0===s?void 0:s.y)&&void 0!==r?r:0)===(null!==(a=null===(l=x.margins)||void 0===l?void 0:l.y)&&void 0!==a?a:0),C=(null!==(d=null===(c=e.separation)||void 0===c?void 0:c.x)&&void 0!==d?d:0)===(null!==(h=null===(u=x.separation)||void 0===u?void 0:u.x)&&void 0!==h?h:0)&&(null!==(p=null===(f=e.separation)||void 0===f?void 0:f.y)&&void 0!==p?p:0)===(null!==(y=null===(m=x.separation)||void 0===m?void 0:m.y)&&void 0!==y?y:0);v&&g&&C||"undefined"!=typeof console&&console.warn(`[Tilemap] Atlas sources '${e.sourceId}' and '${x.id}' share textureAsset='${x.textureAsset}' but differ in regionSize/margins/separation. Frame texture cache may collide and render wrong frames. Use distinct textureAssets per atlas source.`)}else C.set(x.textureAsset,{regionSize:x.regionSize,margins:x.margins,separation:x.separation,sourceId:x.id})}}return{raw:e,sourcesBySlot:g,slotByIdMap:v,tileWidth:e.tileSize.width,tileHeight:e.tileSize.height}}class p{constructor(){this.animations=[],this.lastFrameIdxByKey=new Map}loadFromTileset(e){var t;this.animations=[],this.lastFrameIdxByKey.clear();for(let n=0;n<e.sources.length;n++){const i=e.sources[n];if("atlas"!==i.kind)continue;const o=n+1;for(const e of i.tiles){const n=e.animation;if(!n||!n.frames||0===n.frames.length)continue;const i=n.frames.map(e=>{var t;return{col:e.atlasCoords.col,row:e.atlasCoords.row,durationMs:n.stepMs*(null!==(t=e.durationFactor)&&void 0!==t?t:1)}}),s=i.reduce((e,t)=>e+t.durationMs,0);if(s<=0)continue;const r="randomStart"===n.phase?m(o,e.atlasCoords.col,e.atlasCoords.row,s):0;this.animations.push({sourceSlot:o,col:e.atlasCoords.col,row:e.atlasCoords.row,frames:i,totalDurationMs:s,phase:null!==(t=n.phase)&&void 0!==t?t:"sync",phaseOffsetMs:r})}}}get animationCount(){return this.animations.length}isAnimatedSource(e,t,n){for(const i of this.animations)if(i.sourceSlot===e&&i.col===t&&i.row===n)return!0;return!1}advance(e){const t=new Map,n=new Set;for(const i of this.animations){const o=`${i.sourceSlot},${i.col},${i.row}`,s=((e+i.phaseOffsetMs)%i.totalDurationMs+i.totalDurationMs)%i.totalDurationMs;let r=0,l=0;for(;l<i.frames.length&&(r+=i.frames[l].durationMs,!(s<r));l++);l>=i.frames.length&&(l=i.frames.length-1);const a=i.frames[l];t.set(o,{col:a.col,row:a.row});this.lastFrameIdxByKey.get(o)!==l&&(n.add(o),this.lastFrameIdxByKey.set(o,l))}return{currentFrames:t,dirtyKeys:n}}reset(){this.lastFrameIdxByKey.clear()}}function m(e,t,n,i){let o=73856093*e^19349663*t^83492791*n;o=1274126177*(o^o>>>13),o^=o>>>16;const s=(o>>>0)/4294967295;return Math.floor(s*i)}const y={DIRTY_REBUILD_MS:"tilemap.dirtyRebuild.ms",CULL_CHECK_MS:"tilemap.cullCheck.ms",ANIM_TICK_MS:"tilemap.animTick.ms",DRAWCALLS_COUNT:"tilemap.drawcalls.count",DRAWCALLS_BY_ATLAS:"tilemap.drawcalls.byAtlas",PHYSICS_REBAKE_MS:"tilemap.physicsRebake.ms",GPU_UPLOAD_MS:"tilemap.gpuUpload.ms",GPU_UPLOAD_BYTES:"tilemap.gpuUpload.bytes",AUTOTILE_MS:"tilemap.autotile.ms",PATCH_APPLY_MS:"tilemap.patchApply.ms",DIRTY_PENDING:"tilemap.dirty.pending",DIRTY_FRAMES_BEHIND:"tilemap.dirty.framesBehind",BODIES_TOTAL:"tilemap.bodies.total",BODIES_CREATED:"tilemap.bodies.created",BODIES_DESTROYED:"tilemap.bodies.destroyed",STRATEGY_SPRITE_COUNT:"tilemap.strategy.sprite.count",STRATEGY_MESH_COUNT:"tilemap.strategy.mesh.count",STRATEGY_MESH_FALLBACK_COUNT:"tilemap.strategy.meshFallback.count",SCENECOLLECTION_SKIPPED_COUNT:"tilemap.sceneCollection.skipped.count",CULL_HITS_COUNT:"tilemap.cull.hits",MODE_SWITCH_FAILED_COUNT:"tilemap.modeSwitch.failed",ANIM_TICK_ERROR_COUNT:"tilemap.animTick.error.count",CONTEXT_LOST_COUNT:"tilemap.context.lost"};function v(){return"undefined"!=typeof performance&&performance.now?performance.now():0}function g(e){var t,n,i,o;const s=null==e?void 0:e.perfProbes;return s?{beginTiming:null!==(t=s.beginTiming)&&void 0!==t?t:()=>{},endTiming:null!==(n=s.endTiming)&&void 0!==n?n:()=>{},count:null!==(i=s.count)&&void 0!==i?i:()=>{},gauge:null!==(o=s.gauge)&&void 0!==o?o:()=>{},histogram:s.histogram}:null}function C(e){return e.preference&&"auto"!==e.preference?e.preference:e.atlasesInChunk>1?"sprite":e.nonEmptyCellsInChunk>=192?"mesh":"sprite"}let T=class extends n.Renderer{constructor(){super(...arguments),this.name="Tilemap",this.records={},this.animationDrivers=new Map,this.probes=null,this.isHidden=!1,this.contextLost=!1,this.canvasWithCtxListeners=null}init(){this.renderSystem=this.game.getSystem(n.RendererSystem),this.renderSystem.rendererManager.register(this),this.probes=g(this.game),this.installVisibilityHandlers()}installVisibilityHandlers(){var e,t,n;if("undefined"!=typeof document){try{this.visibilityListener=()=>{this.isHidden=!!document.hidden},document.addEventListener("visibilitychange",this.visibilityListener)}catch(e){}try{const i=null!==(n=null===(t=null===(e=this.renderSystem)||void 0===e?void 0:e.application)||void 0===t?void 0:t.canvas)&&void 0!==n?n:null;i&&"function"==typeof i.addEventListener&&(this.contextLostListener=()=>{this.contextLost=!0,this.probeCount(y.CONTEXT_LOST_COUNT,1),"undefined"!=typeof console&&console.warn("[Tilemap] WebGL context lost — pausing animation tick")},this.contextRestoredListener=()=>{this.contextLost=!1,"undefined"!=typeof console&&console.info("[Tilemap] WebGL context restored — resuming animation tick")},i.addEventListener("webglcontextlost",this.contextLostListener),i.addEventListener("webglcontextrestored",this.contextRestoredListener),this.canvasWithCtxListeners=i)}catch(e){}}}uninstallVisibilityHandlers(){if("undefined"!=typeof document&&this.visibilityListener){try{document.removeEventListener("visibilitychange",this.visibilityListener)}catch(e){}this.visibilityListener=void 0}if(this.canvasWithCtxListeners){try{this.contextLostListener&&this.canvasWithCtxListeners.removeEventListener("webglcontextlost",this.contextLostListener),this.contextRestoredListener&&this.canvasWithCtxListeners.removeEventListener("webglcontextrestored",this.contextRestoredListener)}catch(e){}this.contextLostListener=void 0,this.contextRestoredListener=void 0,this.canvasWithCtxListeners=null}}attachPerfProbes(e){this.probes=e}setCullingBoundsHint(e,t){const n=this.records[e];n&&(n.cullingBoundsHint=null===t?void 0:t)}invalidateChunks(e,t,n){const i=this.records[e];if(!i||0===n.length)return;let o=i.dirtyChunkKeys.get(t);o||(o=new Set,i.dirtyChunkKeys.set(t,o));for(const e of n)o.add(e);let s=0;for(const e of i.dirtyChunkKeys.values())s+=e.size;if(this.probeGauge(y.DIRTY_PENDING,s),!i.flushScheduled){i.flushScheduled=!0;("undefined"!=typeof requestAnimationFrame?requestAnimationFrame:e=>setTimeout(()=>e(0),16))(()=>this.flushDirtyChunks(e))}}flushDirtyChunks(e){var t,n,o,s,r,l,a,c,d,u,h,f,p,m;const v=this.records[e];if(!v)return;if(v.flushScheduled=!1,0===v.dirtyChunkKeys.size)return;if("v2"!==v.mode||!v.loadedTileset)return v.dirtyChunkKeys.clear(),void this.probeGauge(y.DIRTY_PENDING,0);this.probeCount(y.DIRTY_FRAMES_BEHIND,1);const g=v.loadedTileset,C=null!==(t=this.animationDrivers.get(e))&&void 0!==t?t:null,T=this.game;let x=null;if(null==T?void 0:T.gameObjects)for(const t of T.gameObjects){if(t.id!==e)continue;const i=null===(n=t.components)||void 0===n?void 0:n.find(e=>"Tilemap"===(null==e?void 0:e.name));if(i){x=i;break}}const b=null!==(s=null===(o=null==x?void 0:x.cellSize)||void 0===o?void 0:o.width)&&void 0!==s?s:g.tileWidth,S=null!==(l=null===(r=null==x?void 0:x.cellSize)||void 0===r?void 0:r.height)&&void 0!==l?l:g.tileHeight,w=null!==(c=null===(a=null==x?void 0:x.mapOrigin)||void 0===a?void 0:a.x)&&void 0!==c?c:0,I=null!==(u=null===(d=null==x?void 0:x.mapOrigin)||void 0===d?void 0:d.y)&&void 0!==u?u:0;this.probeBegin(y.DIRTY_REBUILD_MS);try{for(const[e,t]of v.dirtyChunkKeys){const n=v.layerContainersV2.get(e);if(!n)continue;const o=null!==(f=null===(h=null==x?void 0:x.layersV2)||void 0===h?void 0:h.find(t=>t.id===e))&&void 0!==f?f:null;if(o)for(const e of t){const t=n.chunkContainers.get(e);if(t){n.container.removeChild(t);try{t.destroy({children:!0})}catch(e){}n.chunkContainers.delete(e)}const s=null===(m=null===(p=o.cellData)||void 0===p?void 0:p.chunks)||void 0===m?void 0:m[e];if(!s||s.nonEmpty<=0)continue;const r=new i.Container;r.label=`chunk-${e}`,this.populateChunkSprites(r,e,s,v,g,b,S,w,I,o,C),n.container.addChild(r),n.chunkContainers.set(e,r)}}}finally{this.probeEnd(y.DIRTY_REBUILD_MS)}v.dirtyChunkKeys.clear(),this.probeGauge(y.DIRTY_PENDING,0),this.requestRedraw()}probeBegin(e){var t;null===(t=this.probes)||void 0===t||t.beginTiming(e)}probeEnd(e){var t;null===(t=this.probes)||void 0===t||t.endTiming(e)}probeCount(e,t=1){var n;null===(n=this.probes)||void 0===n||n.count(e,t)}probeGauge(e,t){var n;null===(n=this.probes)||void 0===n||n.gauge(e,t)}rendererUpdate(e){}update(e){if(this.isHidden||this.contextLost)return;if(0===this.animationDrivers.size)return;this.probeBegin(y.ANIM_TICK_MS);let t=0;try{const e="undefined"!=typeof performance&&performance.now?performance.now():0;for(const[n,i]of this.animationDrivers){const o=this.records[n];if(o&&"v2"===o.mode)try{const n=i.advance(e);if(0===n.dirtyKeys.size)continue;const s=o.loadedTileset;if(!s)continue;let r=!1;for(const e of n.dirtyKeys){const i=o.animatedSpritesByAnimKey.get(e);if(!i||0===i.length)continue;const l=n.currentFrames.get(e);if(!l)continue;const a=e.split(","),c=Number.parseInt(a[0],10),d=this.getAtlasFrameTexture(o,s,{sourceSlot:c,col:l.col,row:l.row});if(d)for(const e of i)e.texture=d,r=!0,t++}r&&this.requestRedraw()}catch(e){this.probeCount(y.ANIM_TICK_ERROR_COUNT,1),"undefined"!=typeof console&&console.error(`[Tilemap] animation tick failed for entity ${n}`,e)}}}finally{this.probeEnd(y.ANIM_TICK_MS),t>0&&this.probeCount("tilemap.anim.spritesSwapped",t)}}componentChanged(t){return r(this,void 0,void 0,function*(){if("Tilemap"!==t.componentName)return;const n=t.component,i=t.gameObject.id;t.type===e.OBSERVER_TYPE.ADD?yield this.handleAdd(i,t.gameObject,n):t.type===e.OBSERVER_TYPE.CHANGE?yield this.handleChange(i,n,t):t.type===e.OBSERVER_TYPE.REMOVE&&this.handleRemove(i)})}handleAdd(e,t,n){return r(this,void 0,void 0,function*(){this.probeBegin(y.DIRTY_REBUILD_MS);try{const o=this.increaseAsyncId(e),s=this.detectMode(n),r=new i.Container,l=this.containerManager.getContainer(e);l&&l.addChildAt(r,0);const a={root:r,layerContainers:[],layerContainersV2:new Map,frameTextures:[],frameTexturesV2:new Map,baseTexture:null,atlasTextures:new Map,loadedTileset:null,mode:s,animatedSpritesByAnimKey:new Map,sceneCollectionWarnedSourceIds:new Set,dirtyChunkKeys:new Map,flushScheduled:!1};this.records[e]=a,"v1"===s?yield this.ensureV1Built(a,e,t,n,o):"v2"===s&&(yield this.ensureV2Built(a,e,t,n,o))}finally{this.probeEnd(y.DIRTY_REBUILD_MS)}})}ensureV1Built(e,t,n,i,o){return r(this,void 0,void 0,function*(){const s=yield this.loadV1Texture(i);this.validateAsyncId(t,o)&&(s?(e.baseTexture=s,this.buildLayersV1(e,i),this.requestRedraw()):"undefined"!=typeof console&&console.error(`GameObject:${n.name}'s Tilemap tileset load error`))})}ensureV2Built(e,t,n,i,o){return r(this,void 0,void 0,function*(){const s=yield this.loadV2Tileset(i);if(!this.validateAsyncId(t,o))return;if(!s)return void("undefined"!=typeof console&&console.error(`GameObject:${n.name}'s Tilemap tilemapRef load error`));if(e.loadedTileset=s,yield this.loadAtlasTextures(e,s),!this.validateAsyncId(t,o))return;const r=new p;r.loadFromTileset(s.raw);const l=r.animationCount>0?r:null;l&&this.animationDrivers.set(t,l),this.buildLayersV2(e,i,l),this.requestRedraw()})}requestRedraw(){var e;try{const t=null===(e=this.renderSystem)||void 0===e?void 0:e.application;(null==t?void 0:t.renderer)&&t.stage&&t.renderer.render(t.stage)}catch(e){"undefined"!=typeof console&&console.warn("[Tilemap] requestRedraw failed",e)}}handleChange(e,t,n){var i,o;return r(this,void 0,void 0,function*(){const s=this.records[e];if(!s)return;const r=null===(o=null===(i=n.prop)||void 0===i?void 0:i.prop)||void 0===o?void 0:o[0];this.probeBegin(y.PATCH_APPLY_MS);try{const i=this.detectMode(t);if(i!==s.mode){const o=this.increaseAsyncId(e);try{if("v1"===s.mode?this.tearDownChildrenV1(s):"v2"===s.mode&&(this.tearDownChildrenV2(s),this.animationDrivers.delete(e)),s.baseTexture=null,s.loadedTileset=null,"v1"===i){const i=yield this.loadV1Texture(t);if(!this.validateAsyncId(e,o))return;if(!i)return s.mode="unknown",this.probeCount(y.MODE_SWITCH_FAILED_COUNT,1),void("undefined"!=typeof console&&console.error(`GameObject:${n.gameObject.name}'s Tilemap mode-switch v→v1 failed (tileset load returned null)`));s.mode="v1",s.baseTexture=i,this.buildLayersV1(s,t),this.requestRedraw()}else if("v2"===i){const i=yield this.loadV2Tileset(t);if(!this.validateAsyncId(e,o))return;if(!i)return s.mode="unknown",this.probeCount(y.MODE_SWITCH_FAILED_COUNT,1),void("undefined"!=typeof console&&console.error(`GameObject:${n.gameObject.name}'s Tilemap mode-switch v→v2 failed (tilemapRef load returned null)`));if(yield this.loadAtlasTextures(s,i),!this.validateAsyncId(e,o))return;s.mode="v2",s.loadedTileset=i;const r=new p;r.loadFromTileset(i.raw);const l=r.animationCount>0?r:null;l&&this.animationDrivers.set(e,l),this.buildLayersV2(s,t,l),this.requestRedraw()}else s.mode="unknown"}catch(e){s.mode="unknown",this.probeCount(y.MODE_SWITCH_FAILED_COUNT,1),"undefined"!=typeof console&&console.error("[Tilemap] mode switch threw",e)}return}if("tileset"===r&&"v1"===s.mode){const n=this.increaseAsyncId(e),i=yield this.loadV1Texture(t);if(!this.validateAsyncId(e,n))return;if(!i)return;this.tearDownChildrenV1(s),s.baseTexture=i,this.buildLayersV1(s,t),this.requestRedraw()}else if("tilemapRef"===r&&"v2"===s.mode){const n=this.increaseAsyncId(e),i=yield this.loadV2Tileset(t);if(!this.validateAsyncId(e,n))return;if(!i)return;if(this.tearDownChildrenV2(s),s.loadedTileset=i,yield this.loadAtlasTextures(s,i),!this.validateAsyncId(e,n))return;this.animationDrivers.delete(e);const o=new p;o.loadFromTileset(i.raw);const r=o.animationCount>0?o:null;r&&this.animationDrivers.set(e,r),this.buildLayersV2(s,t,r),this.requestRedraw()}else if("layersV2"===r&&"v2"===s.mode){this.tearDownChildrenV2(s),this.animationDrivers.delete(e),s.dirtyChunkKeys.clear();const n=s.loadedTileset;let i=null;if(n){const t=new p;t.loadFromTileset(n.raw),t.animationCount>0&&(i=t,this.animationDrivers.set(e,t))}this.buildLayersV2(s,t,i),this.requestRedraw()}}finally{this.probeEnd(y.PATCH_APPLY_MS)}})}handleRemove(e){var t;this.increaseAsyncId(e);const n=this.records[e];if(!n)return;this.tearDownChildrenV1(n),this.tearDownChildrenV2(n);const i=null===(t=this.containerManager)||void 0===t?void 0:t.getContainer(e);i&&i.removeChild(n.root),n.root.destroy({children:!0}),delete this.records[e],this.animationDrivers.delete(e),this.probeGauge("tilemap.records.alive",Object.keys(this.records).length)}detectMode(e){return e.tilemapRef?"v2":e.tileset?"v1":"unknown"}loadV1Texture(t){var n;return r(this,void 0,void 0,function*(){if(!t.tileset)return null;const{instance:i}=yield e.resource.getResource(t.tileset);return null!==(n=i)&&void 0!==n?n:null})}tearDownChildrenV1(e){for(const t of e.layerContainers)e.root.removeChild(t),t.destroy({children:!0});e.layerContainers=[];for(const t of e.frameTextures)try{t.destroy(!1)}catch(e){}e.frameTextures=[]}buildLayersV1(e,t){var n,o,s,r,l,a,c,d,u,h;const f=e.baseTexture;if(!f)return;const p=t.tileWidth||32,m=t.tileHeight||32,y=null!==(n=t.renderTileWidth)&&void 0!==n?n:p,v=null!==(o=t.renderTileHeight)&&void 0!==o?o:m,g=t.tilesetMargin||0,C=t.tilesetSpacing||0,T=null!==(u=null!==(c=null!==(a=null!==(r=null===(s=f.orig)||void 0===s?void 0:s.width)&&void 0!==r?r:null===(l=f.source)||void 0===l?void 0:l.width)&&void 0!==a?a:f.width)&&void 0!==c?c:null===(d=f.frame)||void 0===d?void 0:d.width)&&void 0!==u?u:0,x=T>0?Math.max(1,Math.floor((T-g+C)/(p+C))):1,b=t.tilesetColumns&&t.tilesetColumns>0?t.tilesetColumns:x,S=new Map,w=t=>{var n,o;if(t<=0)return null;const s=t-1,r=S.get(s);if(r)return r;const l=s%b,a=Math.floor(s/b),c=g+l*(p+C),d=g+a*(m+C);try{const t=null!==(o=null!==(n=f.source)&&void 0!==n?n:f.baseTexture)&&void 0!==o?o:f,r=new i.Texture({source:t,frame:new i.Rectangle(c,d,p,m)});return S.set(s,r),e.frameTextures.push(r),r}catch(e){return"undefined"!=typeof console&&console.warn("[Tilemap] Texture slice failed, falling back to base",e),f}};for(const n of t.layers||[]){const t=new i.Container;t.label=null!==(h=n.name)&&void 0!==h?h:"tilemap-layer";const o=n.offsetX||0,s=n.offsetY||0;null!=n.alpha&&(t.alpha=n.alpha),!1===n.visible&&(t.visible=!1);const r=n.data||[],l=n.tint;for(let e=0;e<r.length;e++){const n=r[e];if(n)for(let r=0;r<n.length;r++){const a=n[r];if(!a||a<=0)continue;const c=w(a);if(!c)continue;const d=new i.Sprite(c);d.x=o+r*p,d.y=s+e*m,d.width=y,d.height=v,null!=l&&(d.tint=l),t.addChild(d)}}e.root.addChild(t),e.layerContainers.push(t)}}loadV2Tileset(t){var n,i;return r(this,void 0,void 0,function*(){if(!t.tilemapRef)return null;const o=yield e.resource.getResource(t.tilemapRef);if(!o)return null;const s=null!==(n=o.instance)&&void 0!==n?n:null===(i=o.data)||void 0===i?void 0:i.json;return s&&"tileset"===s.kind?f(s):("undefined"!=typeof console&&console.error(`[Tilemap] resource '${t.tilemapRef}' is not a TileSet document`),null)})}loadAtlasTextures(t,n){return r(this,void 0,void 0,function*(){const i=new Set;for(const e of n.sourcesBySlot)"atlas"===e.kind&&e.textureAsset&&i.add(e.textureAsset);yield Promise.all(Array.from(i).map(n=>r(this,void 0,void 0,function*(){var i,o,s;try{const r=yield e.resource.getResource(n),l=null!==(s=null!==(i=null==r?void 0:r.instance)&&void 0!==i?i:null===(o=null==r?void 0:r.data)||void 0===o?void 0:o.image)&&void 0!==s?s:null;l&&t.atlasTextures.set(n,l)}catch(e){"undefined"!=typeof console&&console.warn(`[Tilemap] failed to load atlas asset '${n}'`,e)}})))})}tearDownChildrenV2(e){for(const{container:t}of e.layerContainersV2.values())e.root.removeChild(t),t.destroy({children:!0});e.layerContainersV2.clear();for(const t of e.frameTexturesV2.values())try{t.destroy(!1)}catch(e){}e.frameTexturesV2.clear(),e.animatedSpritesByAnimKey.clear()}buildLayersV2(e,t,n){var o,s,r,l,a,c,d,u,h,f,p;const m=e.loadedTileset;if(!m)return;const y=null!==(s=null===(o=t.cellSize)||void 0===o?void 0:o.width)&&void 0!==s?s:m.tileWidth,v=null!==(l=null===(r=t.cellSize)||void 0===r?void 0:r.height)&&void 0!==l?l:m.tileHeight,g=null!==(c=null===(a=t.mapOrigin)||void 0===a?void 0:a.x)&&void 0!==c?c:0,C=null!==(u=null===(d=t.mapOrigin)||void 0===d?void 0:d.y)&&void 0!==u?u:0,T=(null!==(h=t.layersV2)&&void 0!==h?h:[]).map((e,t)=>({layer:e,idx:t})).sort((e,t)=>{var n,i;return(null!==(n=e.layer.zIndex)&&void 0!==n?n:0)-(null!==(i=t.layer.zIndex)&&void 0!==i?i:0)});for(const{layer:t}of T){if(!1===t.enabled)continue;const o=new i.Container;o.label=null!==(f=t.name)&&void 0!==f?f:t.id,o.alpha=null!==(p=t.opacity)&&void 0!==p?p:1,o.visible=!1!==t.visible;const s=new Map;this.buildChunksForLayer(e,o,s,t,m,y,v,g,C,n),e.root.addChild(o),e.layerContainersV2.set(t.id,{container:o,chunkContainers:s})}}buildChunksForLayer(e,t,n,o,s,r,l,c,h,f){var p;const m=o.cellData;if(!m||!m.chunks)return;const v=Object.entries(m.chunks).filter(([,e])=>e&&e.nonEmpty>0),g=v.length,T=null!==(p=e.cullingBoundsHint)&&void 0!==p?p:null;let x=0;this.probeBegin(y.CULL_CHECK_MS);for(const[p,m]of v){if(T){const e=p.split(","),t=Number.parseInt(e[0],10),n=Number.parseInt(e[1],10),i=c+t*a*r,o=h+n*a*l,s=o+a*l;if(!(i+a*r>T.minX&&i<T.maxX&&s>T.minY&&o<T.maxY)){x++;continue}}const v=new i.Container;v.label=`chunk-${p}`;let b=1,S=null;try{S=u(m);const e=new Set;for(let t=0;t<S.length;t++){const n=S[t];if(d(n))continue;const i=255&n,o=s.sourcesBySlot[i-1];o&&"atlas"===o.kind&&e.add(i)}b=Math.max(1,e.size)}catch(e){b=1,S=null}let w="sprite";"mesh"===C({nonEmptyCellsInChunk:m.nonEmpty,atlasesInChunk:b,totalChunksVisible:g})?this.tryBuildMeshChunk(v,p,m,s,r,l,c,h,o)?w="mesh":(w="meshFallback",this.probeCount(y.STRATEGY_MESH_FALLBACK_COUNT,1),this.populateChunkSprites(v,p,m,e,s,r,l,c,h,o,f,S)):this.populateChunkSprites(v,p,m,e,s,r,l,c,h,o,f,S),"sprite"===w?this.probeCount(y.STRATEGY_SPRITE_COUNT,1):"mesh"===w&&this.probeCount(y.STRATEGY_MESH_COUNT,1),t.addChild(v),n.set(p,v)}this.probeEnd(y.CULL_CHECK_MS),x>0&&this.probeCount(y.CULL_HITS_COUNT,x)}tryBuildMeshChunk(e,t,n,i,o,s,r,l,a){return!1}populateChunkSprites(e,t,n,o,s,r,l,h,f,p,m,v){let g;if(v)g=v;else try{g=u(n)}catch(e){return void("undefined"!=typeof console&&console.warn(`[Tilemap] chunk decode failed for ${t}`,e))}const C=t.split(","),T=Number.parseInt(C[0],10),x=Number.parseInt(C[1],10),b=T*a,S=x*a,w=function(e){if(!e)return;const t=/^#?([0-9a-fA-F]{6})(?:[0-9a-fA-F]{2})?$/.exec(e);return t?parseInt(t[1],16):void 0}(p.modulate);let I=0;for(let t=0;t<a;t++)for(let n=0;n<a;n++){const u=g[t*a+n];if(d(u))continue;const p=c(u),y=this.getAtlasFrameTexture(o,s,p);if(!y)continue;const v=new i.Sprite(y);if(I++,v.x=h+(b+n)*r,v.y=f+(S+t)*l,v.width=r,v.height=l,p.flipH&&(v.scale.x=-Math.abs(v.scale.x||1)),p.flipV&&(v.scale.y=-Math.abs(v.scale.y||1)),p.transpose&&(v.rotation=Math.PI/2),p.flipH&&(v.x+=r),p.flipV&&(v.y+=l),null!=w&&(v.tint=w),e.addChild(v),m&&m.isAnimatedSource(p.sourceSlot,p.col,p.row)){const e=`${p.sourceSlot},${p.col},${p.row}`;let t=o.animatedSpritesByAnimKey.get(e);t||(t=[],o.animatedSpritesByAnimKey.set(e,t)),t.push(v)}}I>0&&this.probeCount(y.DRAWCALLS_COUNT,I)}getAtlasFrameTexture(e,t,n){var o,s,r,l;const a=t.sourcesBySlot[n.sourceSlot-1];if(!a)return null;if("atlas"!==a.kind)return"sceneCollection"===a.kind&&(this.probeCount(y.SCENECOLLECTION_SKIPPED_COUNT,1),e.sceneCollectionWarnedSourceIds.has(a.id)||(e.sceneCollectionWarnedSourceIds.add(a.id),"undefined"!=typeof console&&console.warn(`[Tilemap] sceneCollection source '${a.id}' cells are not yet rendered (prefab instantiation pending). Skipped cell at slot=${n.sourceSlot} col=${n.col} row=${n.row}.`))),null;const c=e.atlasTextures.get(a.textureAsset);if(!c)return null;const d=null!==(o=a.margins)&&void 0!==o?o:{x:0,y:0},u=null!==(s=a.separation)&&void 0!==s?s:{x:0,y:0},h=a.regionSize.width,f=a.regionSize.height,p=`${a.textureAsset}#${h}x${f}|${d.x},${d.y}|${u.x},${u.y}#${n.col},${n.row}`,m=e.frameTexturesV2.get(p);if(m)return m;const v=d.x+n.col*(h+u.x),g=d.y+n.row*(f+u.y);try{const t=null!==(l=null!==(r=c.source)&&void 0!==r?r:c.baseTexture)&&void 0!==l?l:c,n=new i.Texture({source:t,frame:new i.Rectangle(v,g,h,f)});return e.frameTexturesV2.set(p,n),n}catch(e){return"undefined"!=typeof console&&console.warn(`[Tilemap] frame slice failed for ${p}`,e),null}}destroy(){var e;for(const t in this.records){const n=parseInt(t),i=this.records[n];this.tearDownChildrenV1(i),this.tearDownChildrenV2(i);const o=null===(e=this.containerManager)||void 0===e?void 0:e.getContainer(n);o&&o.removeChild(i.root),i.root.destroy({children:!0}),delete this.records[n]}this.uninstallVisibilityHandlers()}};T.systemName="Tilemap",T=o([e.decorators.componentObserver({Tilemap:[{prop:["tileset"],deep:!1},{prop:["tilemapRef"],deep:!1},{prop:["layersV2"],deep:!1}]})],T);var x=T;const b=["topLeft","top","topRight","right","bottomRight","bottom","bottomLeft","left"];function S(e){var t;let n=0;for(let i=0;i<8;i++){n|=(15&(null!==(t=e[i])&&void 0!==t?t:15))<<4*i}return n>>>0}function w(e,t){return e>>>4*t&15}const I="#version 300 es\nprecision highp float;\n\nin vec2 aPosition;\nin vec2 aTexCoord;\nin vec4 aFlags;\n\nuniform mat3 uProjectionMatrix;\nuniform mat3 uWorldTransformMatrix;\n\nout vec2 vTexCoord;\n\nvoid main() {\n vec3 worldPos = uWorldTransformMatrix * vec3(aPosition, 1.0);\n gl_Position = vec4((uProjectionMatrix * worldPos).xy, 0.0, 1.0);\n\n vec2 uv = aTexCoord;\n if (aFlags.x > 0.5) uv.x = 1.0 - uv.x;\n if (aFlags.y > 0.5) uv.y = 1.0 - uv.y;\n if (aFlags.z > 0.5) { float t = uv.x; uv.x = uv.y; uv.y = t; }\n vTexCoord = uv;\n}\n",_="#version 300 es\nprecision highp float;\n\nin vec2 vTexCoord;\nout vec4 fragColor;\n\nuniform sampler2D uTexture;\nuniform vec4 uModulate;\n\nvoid main() {\n vec4 sampled = texture(uTexture, vTexCoord);\n fragColor = sampled * uModulate;\n if (fragColor.a < 0.01) discard;\n}\n",E={vertex:I,fragment:_},A=16;function R(e,t){const n=new Map,i=new Map;for(const t of e.sources)n.set(t.id,t);for(const e of t.sources)i.set(e.id,e);const o=[],s=[],r=[];for(const e of i.keys())n.has(e)?JSON.stringify(n.get(e))!==JSON.stringify(i.get(e))&&r.push(e):o.push(i.get(e));for(const e of n.keys())i.has(e)||s.push(e);const l=new Set,a=new Set,c=new Set,d=e=>{const t=new Map;if("atlas"!==e.kind)return t;for(const n of e.tiles)t.set(`${e.id}/${n.atlasCoords.col},${n.atlasCoords.row}`,n);return t};for(const[e,t]of i){const i=n.get(e);if(!i){const e=d(t);for(const t of e.keys())l.add(t);continue}const o=d(i),s=d(t);for(const e of s.keys())o.has(e)?JSON.stringify(o.get(e))!==JSON.stringify(s.get(e))&&c.add(e):l.add(e);for(const e of o.keys())s.has(e)||a.add(e)}for(const e of s){const t=d(n.get(e));for(const e of t.keys())a.add(e)}return{addedSources:o,removedSourceIds:s,changedSourceIds:r,addedTilesByKey:l,removedTilesByKey:a,changedTilesByKey:c}}const M=R;function L(e){return`${e.sourceSlot},${e.col},${e.row},${e.altIdx},${e.layerId}`}class O{constructor(e=1e3){this.cache=new Map,this.accessOrder=new Map,this.accessCounter=0,this.maxEntries=e}get(e){const t=L(e),n=this.cache.get(t);return n&&this.accessOrder.set(t,++this.accessCounter),n}set(e,t){const n=L(e);this.cache.set(n,t),this.accessOrder.set(n,++this.accessCounter),this.cache.size>this.maxEntries&&this.evictLRU()}has(e){return this.cache.has(L(e))}clear(){this.cache.clear(),this.accessOrder.clear(),this.accessCounter=0}get size(){return this.cache.size}evictLRU(){let e,t=1/0;for(const[n,i]of this.accessOrder)i<t&&(t=i,e=n);e&&(this.cache.delete(e),this.accessOrder.delete(e))}}function k(e,t,n){return e.map(e=>({vertices:e.vertices.map(e=>({x:e.x+t,y:e.y+n}))}))}function D(e){if(e.length<3)return[];if(!function(e){if(e.length<3)return!0;let t=0;const n=e.length;for(let i=0;i<n;i++){const o=e[i],s=e[(i+1)%n],r=e[(i+2)%n],l=s.x-o.x,a=s.y-o.y,c=r.x-s.x,d=l*(r.y-s.y)-a*c;if(0!==d)if(0===t)t=d>0?1:-1;else if((d>0?1:-1)!==t)return!1}return!0}(e)){const t=new Error(`decomposePolygon: input polygon (${e.length} vertices) is non-convex. This is a placeholder implementation that assumes convex input — concave polygons silently produce invalid Matter.js bodies. Real concave decomposition requires the 'poly-decomp' npm dependency (see ADR-0019 Phase 1). If you need concave physics tiles right now, split into convex parts manually.`);throw"undefined"!=typeof console&&console.error("[Tilemap]",t.message),t}return[{vertices:e.slice()}]}function N(e,t,n,i){return((255&e)<<24|(63&i)<<18|(511&n)<<9|511&t)>>>0}O.prototype.getNum=function(e){return this.get({sourceSlot:e>>>24&255,altIdx:e>>>18&63,row:e>>>9&511,col:511&e,layerId:"__num__"})},O.prototype.setNum=function(e,t){this.set({sourceSlot:e>>>24&255,altIdx:e>>>18&63,row:e>>>9&511,col:511&e,layerId:"__num__"},t)};const B=new class{constructor(){this.builders=new Map}register(e,t){this.builders.set(e,t)}unregister(e){this.builders.delete(e)}has(e){return this.builders.has(e)}build(e,t){const n=this.builders.get(e);return n?n(t):null}listRegisteredNames(){return Array.from(this.builders.keys())}clear(){this.builders.clear()}};function V(e){return 255&e}function $(e){return e>>>8&255}function P(e){return e>>>16&255}function H(e){return e>>>24&31}function K(e,t){var n;const i=[];for(const[o,s]of Object.entries(e.chunksByKey)){const[r,l]=o.split(","),a=Number.parseInt(r,10),c=Number.parseInt(l,10);if(Number.isFinite(a)&&Number.isFinite(c))for(let r=0;r<16;r++)for(let l=0;l<16;l++){const d=s[16*r+l],u=V(d);if(0===u)continue;const h=$(d),f=P(d),p=H(d),m=`${u},${h},${f},${p}`,y=e.physicsByCellKey.get(m);if(!y||0===y.length)continue;const v=e.mapOriginX+(16*a+l)*e.cellWidth+t.worldX,g=e.mapOriginY+(16*c+r)*e.cellHeight+t.worldY;for(const t of y)for(const s of t.polygons){const a=N(u,h,f,p);let c=null===(n=e.cache.getNum(a))||void 0===n?void 0:n.parts;c||(c=D(s.points),e.cache.setNum(a,{parts:c}));const d=k(c,v,g);for(let n=0;n<d.length;n++)i.push({id:`tile-${o}-${l}-${r}-${t.layerId}-${n}`,vertices:d[n].vertices,centerX:v+e.cellWidth/2,centerY:g+e.cellHeight/2,isStatic:!0,oneWay:t.oneWay,friction:t.friction,restitution:t.restitution,metadata:{layerId:t.layerId,chunkKey:o,cellLocal:[l,r]}})}}}return i}try{e.resource.registerResourceType("TILESET")}catch(e){}try{e.resource.registerInstance("TILESET",e=>{var t,n,i,o;const s=null===(t=e.data)||void 0===t?void 0:t.json,r=null===(i=null===(n=e.src)||void 0===n?void 0:n.json)||void 0===i?void 0:i.data;return null!==(o=null!=s?s:r)&&void 0!==o?o:null})}catch(e){}exports.ADR_0019_NATIVE_REGISTRY_AVAILABLE=!1,exports.CHUNK_SIZE=a,exports.DecompositionCache=O,exports.MAX_TERRAIN_ID=14,exports.NEIGHBOR_DIRECTIONS=b,exports.NO_NEIGHBOR=15,exports.PeeringBitIndex=class{constructor(e){this.terrainSetIndex=e,this.exact=new Map,this.wildcards=[]}add(e,t){var n;const i=[],o=[];for(let e=0;e<8;e++){const n=null==t?void 0:t[b[e]];void 0===n?(i.push(15),o.push(0)):(i.push(15&n),o.push(15))}const s=S(i),r=S(o);if(o.every(e=>15===e)){const t=null!==(n=this.exact.get(s))&&void 0!==n?n:[];t.push(e),this.exact.set(s,t)}else this.wildcards.push({key:s,mask:r,candidate:e})}match(e){const t=S(e),n=this.exact.get(t);if(n&&n.length>0)return{candidates:n.slice(),exactMatch:!0,bestHammingDistance:0};let i=1/0,o=[];for(const{key:e,mask:n,candidate:s}of this.wildcards){let r=0,l=!0;for(let o=0;o<8;o++){if(0===w(n,o))continue;if(w(t,o)!==w(e,o)&&(r++,r>i)){l=!1;break}}l&&(r<i?(i=r,o=[s]):r===i&&o.push(s))}return{candidates:o,exactMatch:!1,bestHammingDistance:i===1/0?-1:i}}get exactBucketCount(){return this.exact.size}get wildcardCount(){return this.wildcards.length}},exports.TILEMAP_BODY_SOURCE_REGISTRY=B,exports.TILEMAP_PROBE_NAMES=y,exports.TILE_FRAG_SHADER=_,exports.TILE_SHADER_SOURCES=E,exports.TILE_VERT_SHADER=I,exports.TileAnimationDriver=p,exports.Tilemap=l,exports.TilemapSystem=x,exports.adaptGamePerfProbes=g,exports.buildChunkGeometry=function(e){const{cells:t,chunkWorldX:n,chunkWorldY:i,cellWidth:o,cellHeight:s,atlasInfo:r}=e;if(256!==t.length)throw new Error(`buildChunkGeometry: cells length ${t.length} != 256`);let l=0;for(let e=0;e<t.length;e++)d(t[e])||l++;const a=new Float32Array(4*l*8),u=new Uint16Array(6*l);let h=0,f=0,p=0;for(let e=0;e<A;e++)for(let l=0;l<A;l++){const m=t[e*A+l];if(d(m))continue;const y=c(m),v=n+l*o,g=i+e*s,C=v+o,T=g+s,x=(r.margins.x+y.col*(r.regionWidth+r.separation.x))/r.textureWidth,b=x+r.regionWidth/r.textureWidth,S=(r.margins.y+y.row*(r.regionHeight+r.separation.y))/r.textureHeight,w=S+r.regionHeight/r.textureHeight,I=y.flipH?1:0,_=y.flipV?1:0,E=y.transpose?1:0,R=0,M=(e,t,n,i)=>{a[h++]=e,a[h++]=t,a[h++]=n,a[h++]=i,a[h++]=I,a[h++]=_,a[h++]=E,a[h++]=R};M(v,g,x,S),M(C,g,b,S),M(C,T,b,w),M(v,T,x,w);const L=4*p;u[f++]=L,u[f++]=L+1,u[f++]=L+2,u[f++]=L,u[f++]=L+2,u[f++]=L+3,p++}return{vertexData:a,indices:u,quadCount:p}},exports.buildChunkMesh=function(e){const t=new i.Container;return t.label=`chunk-mesh-stub-${e.chunkKey}`,t},exports.buildTileMapStaticBodies=K,exports.buildTileMapStaticBodyDefinitions=function(e,t,n){var i,o;let s;null==n||n.beginTiming(y.PHYSICS_REBAKE_MS);try{s=K(e,t)}finally{null==n||n.endTiming(y.PHYSICS_REBAKE_MS)}const r=new Map;for(const e of s){const t=null!==(o=null===(i=e.metadata)||void 0===i?void 0:i.layerId)&&void 0!==o?o:"<unlabeled>";let n=r.get(t);n||(n=[],r.set(t,n)),n.push(e)}const l=s.length;return null==n||n.gauge(y.BODIES_TOTAL,l),l>0&&(null==n||n.count(y.BODIES_CREATED,l)),{bodies:s,totalBodyCount:l,bodiesByLayerId:r}},exports.cacheKeyOf=L,exports.cacheKeyOfNum=N,exports.computeAffectedChunks=function(e,t,n){const i=new Set,o=(e,i,o)=>{const s=t.get(e);if(!s)return!1;const r=`${s}/${i},${o}`;return n.changedTilesByKey.has(r)||n.removedTilesByKey.has(r)||n.addedTilesByKey.has(r)};for(const[t,n]of Object.entries(e))for(let e=0;e<n.length;e++){const s=n[e],r=255&s;if(0===r)continue;if(o(r,s>>>8&255,s>>>16&255)){i.add(t);break}}return i},exports.createInMemoryProbeRegistry=function(){const e=new Map,t=new Map,n=new Map,i=new Map;return{beginTiming(t){e.set(t,v())},endTiming(n){const i=e.get(n);if(void 0===i)return;e.delete(n);const o=v()-i;t.has(n)||t.set(n,[]),t.get(n).push(o)},count(e,t=1){var i;n.set(e,(null!==(i=n.get(e))&&void 0!==i?i:0)+t)},gauge(e,t){i.set(e,t)},histogram(e,t){this.count(`${e}.histN`),this.count(`${e}.histSum`,t)},timings:t,counts:n,gauges:i}},exports.decodeChunk=u,exports.decomposePolygon=D,exports.diffTilesetDocuments=M,exports.diffTilesetForChunkRebuild=R,exports.estimateChunkMeshMemoryKB=function(e){return Math.ceil(11)},exports.estimateSpriteNodes=function(e){return 1+e},exports.expandSceneCollectionSource=function(e){return"sceneCollection"!==e.kind?[]:e.prefabRefs.map((t,n)=>({sourceId:e.id,prefabName:t,index:n}))},exports.extractPhysicsByCellKey=function(e){const t=new Map;for(let n=0;n<e.sources.length;n++){const i=e.sources[n];if(!i||"atlas"!==i.kind||!i.tiles)continue;const o=n+1;for(const e of i.tiles){const{col:n,row:i}=e.atlasCoords;for(const s of e.alternatives){if(!s.physics||0===s.physics.length)continue;const e=`${o},${n},${i},${31&s.altId}`;t.set(e,s.physics)}}}return t},exports.getRequiredTilemapProbes=function(){return Object.values(y)},exports.isEmptyCellValue=d,exports.isMeshPathAvailable=function(){return!1},exports.makeLoadedTileset=f,exports.pickAutotileCandidate=function(e,t){if(0===e.length)return null;if(1===e.length)return e[0];const n=e.reduce((e,t)=>e+(t.probability>0?t.probability:1),0),i=t()*n;let o=0;for(const t of e)if(o+=t.probability>0?t.probability:1,i<o)return t;return e[e.length-1]},exports.resolveCellPrefabName=function(e,t){var n;const i=255&e;if(0===i)return null;const o=t[i-1];if(!o||"sceneCollection"!==o.kind)return null;const s=e>>>8&255;return null!==(n=o.prefabRefs[s])&&void 0!==n?n:null},exports.resolveChunkRenderStrategy=C,exports.translateConvexParts=k,exports.unpackCell=c;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@eva/eva.js"),t=require("@eva/inspector-decorator"),n=require("@eva/plugin-renderer"),i=require("pixi.js");function o(e,t,n,i){var o,s=arguments.length,r=s<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,n):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,n,i);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(r=(s<3?o(r):s>3?o(t,n,r):o(t,n))||r);return s>3&&r&&Object.defineProperty(t,n,r),r}function s(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function r(e,t,n,i){return new(n||(n=Promise))(function(o,s){function r(e){try{a(i.next(e))}catch(e){s(e)}}function l(e){try{a(i.throw(e))}catch(e){s(e)}}function a(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(r,l)}a((i=i.apply(e,t||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;class l extends e.Component{constructor(){super(...arguments),this.tileset="",this.tileWidth=32,this.tileHeight=32,this.tilesetSpacing=0,this.tilesetMargin=0,this.layers=[],this.tilemapRef="",this.layersV2=void 0}init(e){e&&Object.assign(this,e)}}l.componentName="Tilemap",o([t.type("string"),s("design:type",String)],l.prototype,"tileset",void 0),o([t.type("number"),s("design:type",Number)],l.prototype,"tileWidth",void 0),o([t.type("number"),s("design:type",Number)],l.prototype,"tileHeight",void 0),o([t.type("number"),s("design:type",Number)],l.prototype,"tilesetSpacing",void 0),o([t.type("number"),s("design:type",Number)],l.prototype,"tilesetMargin",void 0),o([t.type("string"),s("design:type",String)],l.prototype,"tilemapRef",void 0);const a=16;function c(e){return{sourceSlot:255&e,col:e>>>8&255,row:e>>>16&255,altIdx:e>>>24&31,flipH:1==(e>>>29&1),flipV:1==(e>>>30&1),transpose:1==(e>>>31&1)}}function d(e){return!(255&e)}function u(e){const t=function(e){if("function"==typeof atob){const t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n}const t=globalThis.Buffer;if(t)return new Uint8Array(t.from(e,"base64"));const n=e.replace(/[^A-Za-z0-9+/]/g,""),i=e.endsWith("==")?2:e.endsWith("=")?1:0,o=Math.floor(3*n.length/4)-i,s=new Uint8Array(o);let r=0;for(let e=0;e<n.length;e+=4){const t=h.indexOf(n[e])<<18|h.indexOf(n[e+1])<<12|(n[e+2]?h.indexOf(n[e+2]):0)<<6|(n[e+3]?h.indexOf(n[e+3]):0);r<o&&(s[r++]=t>>16&255),r<o&&(s[r++]=t>>8&255),r<o&&(s[r++]=255&t)}return s}(e.blob);if(1024!==t.byteLength)throw new Error(`decodeChunk: expected 1024 bytes, got ${t.byteLength}`);const n=new Uint8Array(t.byteLength);return n.set(t),new Int32Array(n.buffer)}const h="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function f(e){var t,n,i,o,s,r,l,a,c,d,u,h,f,p,m,y;const v=new Map,g=[],C=new Map;for(let T=0;T<e.sources.length;T++){const x=e.sources[T];if(g.push(x),v.set(x.id,T+1),"atlas"===x.kind&&x.textureAsset){const e=C.get(x.textureAsset);if(e){const v=e.regionSize.width===x.regionSize.width&&e.regionSize.height===x.regionSize.height,g=(null!==(n=null===(t=e.margins)||void 0===t?void 0:t.x)&&void 0!==n?n:0)===(null!==(o=null===(i=x.margins)||void 0===i?void 0:i.x)&&void 0!==o?o:0)&&(null!==(r=null===(s=e.margins)||void 0===s?void 0:s.y)&&void 0!==r?r:0)===(null!==(a=null===(l=x.margins)||void 0===l?void 0:l.y)&&void 0!==a?a:0),C=(null!==(d=null===(c=e.separation)||void 0===c?void 0:c.x)&&void 0!==d?d:0)===(null!==(h=null===(u=x.separation)||void 0===u?void 0:u.x)&&void 0!==h?h:0)&&(null!==(p=null===(f=e.separation)||void 0===f?void 0:f.y)&&void 0!==p?p:0)===(null!==(y=null===(m=x.separation)||void 0===m?void 0:m.y)&&void 0!==y?y:0);v&&g&&C||"undefined"!=typeof console&&console.warn(`[Tilemap] Atlas sources '${e.sourceId}' and '${x.id}' share textureAsset='${x.textureAsset}' but differ in regionSize/margins/separation. Frame texture cache may collide and render wrong frames. Use distinct textureAssets per atlas source.`)}else C.set(x.textureAsset,{regionSize:x.regionSize,margins:x.margins,separation:x.separation,sourceId:x.id})}}return{raw:e,sourcesBySlot:g,slotByIdMap:v,tileWidth:e.tileSize.width,tileHeight:e.tileSize.height}}class p{constructor(){this.animations=[],this.lastFrameIdxByKey=new Map}loadFromTileset(e){var t;this.animations=[],this.lastFrameIdxByKey.clear();for(let n=0;n<e.sources.length;n++){const i=e.sources[n];if("atlas"!==i.kind)continue;const o=n+1;for(const e of i.tiles){const n=e.animation;if(!n||!n.frames||0===n.frames.length)continue;const i=n.frames.map(e=>{var t;return{col:e.atlasCoords.col,row:e.atlasCoords.row,durationMs:n.stepMs*(null!==(t=e.durationFactor)&&void 0!==t?t:1)}}),s=i.reduce((e,t)=>e+t.durationMs,0);if(s<=0)continue;const r="randomStart"===n.phase?m(o,e.atlasCoords.col,e.atlasCoords.row,s):0;this.animations.push({sourceSlot:o,col:e.atlasCoords.col,row:e.atlasCoords.row,frames:i,totalDurationMs:s,phase:null!==(t=n.phase)&&void 0!==t?t:"sync",phaseOffsetMs:r})}}}get animationCount(){return this.animations.length}isAnimatedSource(e,t,n){for(const i of this.animations)if(i.sourceSlot===e&&i.col===t&&i.row===n)return!0;return!1}advance(e){const t=new Map,n=new Set;for(const i of this.animations){const o=`${i.sourceSlot},${i.col},${i.row}`,s=((e+i.phaseOffsetMs)%i.totalDurationMs+i.totalDurationMs)%i.totalDurationMs;let r=0,l=0;for(;l<i.frames.length&&(r+=i.frames[l].durationMs,!(s<r));l++);l>=i.frames.length&&(l=i.frames.length-1);const a=i.frames[l];t.set(o,{col:a.col,row:a.row});this.lastFrameIdxByKey.get(o)!==l&&(n.add(o),this.lastFrameIdxByKey.set(o,l))}return{currentFrames:t,dirtyKeys:n}}reset(){this.lastFrameIdxByKey.clear()}}function m(e,t,n,i){let o=73856093*e^19349663*t^83492791*n;o=1274126177*(o^o>>>13),o^=o>>>16;const s=(o>>>0)/4294967295;return Math.floor(s*i)}const y={DIRTY_REBUILD_MS:"tilemap.dirtyRebuild.ms",CULL_CHECK_MS:"tilemap.cullCheck.ms",ANIM_TICK_MS:"tilemap.animTick.ms",DRAWCALLS_COUNT:"tilemap.drawcalls.count",DRAWCALLS_BY_ATLAS:"tilemap.drawcalls.byAtlas",PHYSICS_REBAKE_MS:"tilemap.physicsRebake.ms",GPU_UPLOAD_MS:"tilemap.gpuUpload.ms",GPU_UPLOAD_BYTES:"tilemap.gpuUpload.bytes",AUTOTILE_MS:"tilemap.autotile.ms",PATCH_APPLY_MS:"tilemap.patchApply.ms",DIRTY_PENDING:"tilemap.dirty.pending",DIRTY_FRAMES_BEHIND:"tilemap.dirty.framesBehind",BODIES_TOTAL:"tilemap.bodies.total",BODIES_CREATED:"tilemap.bodies.created",BODIES_DESTROYED:"tilemap.bodies.destroyed",STRATEGY_SPRITE_COUNT:"tilemap.strategy.sprite.count",STRATEGY_MESH_COUNT:"tilemap.strategy.mesh.count",STRATEGY_MESH_FALLBACK_COUNT:"tilemap.strategy.meshFallback.count",SCENECOLLECTION_SKIPPED_COUNT:"tilemap.sceneCollection.skipped.count",CULL_HITS_COUNT:"tilemap.cull.hits",MODE_SWITCH_FAILED_COUNT:"tilemap.modeSwitch.failed",ANIM_TICK_ERROR_COUNT:"tilemap.animTick.error.count",CONTEXT_LOST_COUNT:"tilemap.context.lost"};function v(){return"undefined"!=typeof performance&&performance.now?performance.now():0}function g(e){var t,n,i,o;const s=null==e?void 0:e.perfProbes;return s?{beginTiming:null!==(t=s.beginTiming)&&void 0!==t?t:()=>{},endTiming:null!==(n=s.endTiming)&&void 0!==n?n:()=>{},count:null!==(i=s.count)&&void 0!==i?i:()=>{},gauge:null!==(o=s.gauge)&&void 0!==o?o:()=>{},histogram:s.histogram}:null}function C(e){return e.preference&&"auto"!==e.preference?e.preference:e.atlasesInChunk>1?"sprite":e.nonEmptyCellsInChunk>=192?"mesh":"sprite"}let T=class extends n.Renderer{constructor(){super(...arguments),this.name="Tilemap",this.records={},this.animationDrivers=new Map,this.probes=null,this.isHidden=!1,this.contextLost=!1,this.canvasWithCtxListeners=null}init(){this.renderSystem=this.game.getSystem(n.RendererSystem),this.renderSystem.rendererManager.register(this),this.probes=g(this.game),this.installVisibilityHandlers()}installVisibilityHandlers(){var e,t,n;if("undefined"!=typeof document){try{this.visibilityListener=()=>{this.isHidden=!!document.hidden},document.addEventListener("visibilitychange",this.visibilityListener)}catch(e){}try{const i=null!==(n=null===(t=null===(e=this.renderSystem)||void 0===e?void 0:e.application)||void 0===t?void 0:t.canvas)&&void 0!==n?n:null;i&&"function"==typeof i.addEventListener&&(this.contextLostListener=()=>{this.contextLost=!0,this.probeCount(y.CONTEXT_LOST_COUNT,1),"undefined"!=typeof console&&console.warn("[Tilemap] WebGL context lost — pausing animation tick")},this.contextRestoredListener=()=>{this.contextLost=!1,"undefined"!=typeof console&&console.info("[Tilemap] WebGL context restored — resuming animation tick")},i.addEventListener("webglcontextlost",this.contextLostListener),i.addEventListener("webglcontextrestored",this.contextRestoredListener),this.canvasWithCtxListeners=i)}catch(e){}}}uninstallVisibilityHandlers(){if("undefined"!=typeof document&&this.visibilityListener){try{document.removeEventListener("visibilitychange",this.visibilityListener)}catch(e){}this.visibilityListener=void 0}if(this.canvasWithCtxListeners){try{this.contextLostListener&&this.canvasWithCtxListeners.removeEventListener("webglcontextlost",this.contextLostListener),this.contextRestoredListener&&this.canvasWithCtxListeners.removeEventListener("webglcontextrestored",this.contextRestoredListener)}catch(e){}this.contextLostListener=void 0,this.contextRestoredListener=void 0,this.canvasWithCtxListeners=null}}attachPerfProbes(e){this.probes=e}setCullingBoundsHint(e,t){const n=this.records[e];n&&(n.cullingBoundsHint=null===t?void 0:t)}invalidateChunks(e,t,n){const i=this.records[e];if(!i||0===n.length)return;let o=i.dirtyChunkKeys.get(t);o||(o=new Set,i.dirtyChunkKeys.set(t,o));for(const e of n)o.add(e);let s=0;for(const e of i.dirtyChunkKeys.values())s+=e.size;if(this.probeGauge(y.DIRTY_PENDING,s),!i.flushScheduled){i.flushScheduled=!0;("undefined"!=typeof requestAnimationFrame?requestAnimationFrame:e=>setTimeout(()=>e(0),16))(()=>this.flushDirtyChunks(e))}}flushDirtyChunks(e){var t,n,o,s,r,l,a,c,d,u,h,f,p,m;const v=this.records[e];if(!v)return;if(v.flushScheduled=!1,0===v.dirtyChunkKeys.size)return;if("v2"!==v.mode||!v.loadedTileset)return v.dirtyChunkKeys.clear(),void this.probeGauge(y.DIRTY_PENDING,0);this.probeCount(y.DIRTY_FRAMES_BEHIND,1);const g=v.loadedTileset,C=null!==(t=this.animationDrivers.get(e))&&void 0!==t?t:null,T=this.game;let x=null;if(null==T?void 0:T.gameObjects)for(const t of T.gameObjects){if(t.id!==e)continue;const i=null===(n=t.components)||void 0===n?void 0:n.find(e=>"Tilemap"===(null==e?void 0:e.name));if(i){x=i;break}}const b=null!==(s=null===(o=null==x?void 0:x.cellSize)||void 0===o?void 0:o.width)&&void 0!==s?s:g.tileWidth,S=null!==(l=null===(r=null==x?void 0:x.cellSize)||void 0===r?void 0:r.height)&&void 0!==l?l:g.tileHeight,w=null!==(c=null===(a=null==x?void 0:x.mapOrigin)||void 0===a?void 0:a.x)&&void 0!==c?c:0,I=null!==(u=null===(d=null==x?void 0:x.mapOrigin)||void 0===d?void 0:d.y)&&void 0!==u?u:0;this.probeBegin(y.DIRTY_REBUILD_MS);try{for(const[e,t]of v.dirtyChunkKeys){const n=v.layerContainersV2.get(e);if(!n)continue;const o=null!==(f=null===(h=null==x?void 0:x.layersV2)||void 0===h?void 0:h.find(t=>t.id===e))&&void 0!==f?f:null;if(o)for(const e of t){const t=n.chunkContainers.get(e);if(t){n.container.removeChild(t);try{t.destroy({children:!0})}catch(e){}n.chunkContainers.delete(e)}const s=null===(m=null===(p=o.cellData)||void 0===p?void 0:p.chunks)||void 0===m?void 0:m[e];if(!s||s.nonEmpty<=0)continue;const r=new i.Container;r.label=`chunk-${e}`,this.populateChunkSprites(r,e,s,v,g,b,S,w,I,o,C),n.container.addChild(r),n.chunkContainers.set(e,r)}}}finally{this.probeEnd(y.DIRTY_REBUILD_MS)}v.dirtyChunkKeys.clear(),this.probeGauge(y.DIRTY_PENDING,0),this.requestRedraw()}probeBegin(e){var t;null===(t=this.probes)||void 0===t||t.beginTiming(e)}probeEnd(e){var t;null===(t=this.probes)||void 0===t||t.endTiming(e)}probeCount(e,t=1){var n;null===(n=this.probes)||void 0===n||n.count(e,t)}probeGauge(e,t){var n;null===(n=this.probes)||void 0===n||n.gauge(e,t)}rendererUpdate(e){}update(e){if(super.update(e),this.isHidden||this.contextLost)return;if(0===this.animationDrivers.size)return;this.probeBegin(y.ANIM_TICK_MS);let t=0;try{const e="undefined"!=typeof performance&&performance.now?performance.now():0;for(const[n,i]of this.animationDrivers){const o=this.records[n];if(o&&"v2"===o.mode)try{const n=i.advance(e);if(0===n.dirtyKeys.size)continue;const s=o.loadedTileset;if(!s)continue;let r=!1;for(const e of n.dirtyKeys){const i=o.animatedSpritesByAnimKey.get(e);if(!i||0===i.length)continue;const l=n.currentFrames.get(e);if(!l)continue;const a=e.split(","),c=Number.parseInt(a[0],10),d=this.getAtlasFrameTexture(o,s,{sourceSlot:c,col:l.col,row:l.row});if(d)for(const e of i)e.texture=d,r=!0,t++}r&&this.requestRedraw()}catch(e){this.probeCount(y.ANIM_TICK_ERROR_COUNT,1),"undefined"!=typeof console&&console.error(`[Tilemap] animation tick failed for entity ${n}`,e)}}}finally{this.probeEnd(y.ANIM_TICK_MS),t>0&&this.probeCount("tilemap.anim.spritesSwapped",t)}}componentChanged(t){return r(this,void 0,void 0,function*(){if("Tilemap"!==t.componentName)return;const n=t.component,i=t.gameObject.id;t.type===e.OBSERVER_TYPE.ADD?yield this.handleAdd(i,t.gameObject,n):t.type===e.OBSERVER_TYPE.CHANGE?this.records[i]?yield this.handleChange(i,n,t):yield this.handleAdd(i,t.gameObject,n):t.type===e.OBSERVER_TYPE.REMOVE&&this.handleRemove(i)})}handleAdd(e,t,n){return r(this,void 0,void 0,function*(){this.probeBegin(y.DIRTY_REBUILD_MS);try{const o=this.increaseAsyncId(e),s=this.detectMode(n),r=new i.Container,l=this.containerManager.getContainer(e);l&&l.addChildAt(r,0);const a={root:r,layerContainers:[],layerContainersV2:new Map,frameTextures:[],frameTexturesV2:new Map,baseTexture:null,atlasTextures:new Map,loadedTileset:null,mode:s,animatedSpritesByAnimKey:new Map,sceneCollectionWarnedSourceIds:new Set,dirtyChunkKeys:new Map,flushScheduled:!1};this.records[e]=a,"v1"===s?yield this.ensureV1Built(a,e,t,n,o):"v2"===s&&(yield this.ensureV2Built(a,e,t,n,o))}finally{this.probeEnd(y.DIRTY_REBUILD_MS)}})}ensureV1Built(e,t,n,i,o){return r(this,void 0,void 0,function*(){const s=yield this.loadV1Texture(i);this.validateAsyncId(t,o)&&(s?(e.baseTexture=s,this.buildLayersV1(e,i),this.requestRedraw()):"undefined"!=typeof console&&console.error(`GameObject:${n.name}'s Tilemap tileset load error`))})}ensureV2Built(e,t,n,i,o){return r(this,void 0,void 0,function*(){const s=yield this.loadV2Tileset(i);if(!this.validateAsyncId(t,o))return;if(!s)return void("undefined"!=typeof console&&console.error(`GameObject:${n.name}'s Tilemap tilemapRef load error`));if(e.loadedTileset=s,yield this.loadAtlasTextures(e,s),!this.validateAsyncId(t,o))return;const r=new p;r.loadFromTileset(s.raw);const l=r.animationCount>0?r:null;l&&this.animationDrivers.set(t,l),this.buildLayersV2(e,i,l),this.requestRedraw()})}requestRedraw(){var e;try{const t=null===(e=this.renderSystem)||void 0===e?void 0:e.application;(null==t?void 0:t.renderer)&&t.stage&&t.renderer.render(t.stage)}catch(e){"undefined"!=typeof console&&console.warn("[Tilemap] requestRedraw failed",e)}}handleChange(e,t,n){var i,o;return r(this,void 0,void 0,function*(){const s=this.records[e];if(!s)return;const r=null===(o=null===(i=n.prop)||void 0===i?void 0:i.prop)||void 0===o?void 0:o[0];this.probeBegin(y.PATCH_APPLY_MS);try{const i=this.detectMode(t);if(i!==s.mode){const o=this.increaseAsyncId(e);try{if("v1"===s.mode?this.tearDownChildrenV1(s):"v2"===s.mode&&(this.tearDownChildrenV2(s),this.animationDrivers.delete(e)),s.baseTexture=null,s.loadedTileset=null,"v1"===i){const i=yield this.loadV1Texture(t);if(!this.validateAsyncId(e,o))return;if(!i)return s.mode="unknown",this.probeCount(y.MODE_SWITCH_FAILED_COUNT,1),void("undefined"!=typeof console&&console.error(`GameObject:${n.gameObject.name}'s Tilemap mode-switch v→v1 failed (tileset load returned null)`));s.mode="v1",s.baseTexture=i,this.buildLayersV1(s,t),this.requestRedraw()}else if("v2"===i){const i=yield this.loadV2Tileset(t);if(!this.validateAsyncId(e,o))return;if(!i)return s.mode="unknown",this.probeCount(y.MODE_SWITCH_FAILED_COUNT,1),void("undefined"!=typeof console&&console.error(`GameObject:${n.gameObject.name}'s Tilemap mode-switch v→v2 failed (tilemapRef load returned null)`));if(yield this.loadAtlasTextures(s,i),!this.validateAsyncId(e,o))return;s.mode="v2",s.loadedTileset=i;const r=new p;r.loadFromTileset(i.raw);const l=r.animationCount>0?r:null;l&&this.animationDrivers.set(e,l),this.buildLayersV2(s,t,l),this.requestRedraw()}else s.mode="unknown"}catch(e){s.mode="unknown",this.probeCount(y.MODE_SWITCH_FAILED_COUNT,1),"undefined"!=typeof console&&console.error("[Tilemap] mode switch threw",e)}return}if("tileset"===r&&"v1"===s.mode){const n=this.increaseAsyncId(e),i=yield this.loadV1Texture(t);if(!this.validateAsyncId(e,n))return;if(!i)return;this.tearDownChildrenV1(s),s.baseTexture=i,this.buildLayersV1(s,t),this.requestRedraw()}else if("tilemapRef"===r&&"v2"===s.mode){const n=this.increaseAsyncId(e),i=yield this.loadV2Tileset(t);if(!this.validateAsyncId(e,n))return;if(!i)return;if(this.tearDownChildrenV2(s),s.loadedTileset=i,yield this.loadAtlasTextures(s,i),!this.validateAsyncId(e,n))return;this.animationDrivers.delete(e);const o=new p;o.loadFromTileset(i.raw);const r=o.animationCount>0?o:null;r&&this.animationDrivers.set(e,r),this.buildLayersV2(s,t,r),this.requestRedraw()}else if("layersV2"===r&&"v2"===s.mode){this.tearDownChildrenV2(s),this.animationDrivers.delete(e),s.dirtyChunkKeys.clear();const n=s.loadedTileset;let i=null;if(n){const t=new p;t.loadFromTileset(n.raw),t.animationCount>0&&(i=t,this.animationDrivers.set(e,t))}this.buildLayersV2(s,t,i),this.requestRedraw()}}finally{this.probeEnd(y.PATCH_APPLY_MS)}})}handleRemove(e){var t;this.increaseAsyncId(e);const n=this.records[e];if(!n)return;this.tearDownChildrenV1(n),this.tearDownChildrenV2(n);const i=null===(t=this.containerManager)||void 0===t?void 0:t.getContainer(e);i&&i.removeChild(n.root),n.root.destroy({children:!0}),delete this.records[e],this.animationDrivers.delete(e),this.probeGauge("tilemap.records.alive",Object.keys(this.records).length)}detectMode(e){return e.tilemapRef?"v2":e.tileset?"v1":"unknown"}loadV1Texture(t){var n;return r(this,void 0,void 0,function*(){if(!t.tileset)return null;const{instance:i}=yield e.resource.getResource(t.tileset);return null!==(n=i)&&void 0!==n?n:null})}tearDownChildrenV1(e){for(const t of e.layerContainers)e.root.removeChild(t),t.destroy({children:!0});e.layerContainers=[];for(const t of e.frameTextures)try{t.destroy(!1)}catch(e){}e.frameTextures=[]}buildLayersV1(e,t){var n,o,s,r,l,a,c,d,u,h;const f=e.baseTexture;if(!f)return;const p=t.tileWidth||32,m=t.tileHeight||32,y=null!==(n=t.renderTileWidth)&&void 0!==n?n:p,v=null!==(o=t.renderTileHeight)&&void 0!==o?o:m,g=t.tilesetMargin||0,C=t.tilesetSpacing||0,T=null!==(u=null!==(c=null!==(a=null!==(r=null===(s=f.orig)||void 0===s?void 0:s.width)&&void 0!==r?r:null===(l=f.source)||void 0===l?void 0:l.width)&&void 0!==a?a:f.width)&&void 0!==c?c:null===(d=f.frame)||void 0===d?void 0:d.width)&&void 0!==u?u:0,x=T>0?Math.max(1,Math.floor((T-g+C)/(p+C))):1,b=t.tilesetColumns&&t.tilesetColumns>0?t.tilesetColumns:x,S=new Map,w=t=>{var n,o;if(t<=0)return null;const s=t-1,r=S.get(s);if(r)return r;const l=s%b,a=Math.floor(s/b),c=g+l*(p+C),d=g+a*(m+C);try{const t=null!==(o=null!==(n=f.source)&&void 0!==n?n:f.baseTexture)&&void 0!==o?o:f,r=new i.Texture({source:t,frame:new i.Rectangle(c,d,p,m)});return S.set(s,r),e.frameTextures.push(r),r}catch(e){return"undefined"!=typeof console&&console.warn("[Tilemap] Texture slice failed, falling back to base",e),f}};for(const n of t.layers||[]){const t=new i.Container;t.label=null!==(h=n.name)&&void 0!==h?h:"tilemap-layer";const o=n.offsetX||0,s=n.offsetY||0;null!=n.alpha&&(t.alpha=n.alpha),!1===n.visible&&(t.visible=!1);const r=n.data||[],l=n.tint;for(let e=0;e<r.length;e++){const n=r[e];if(n)for(let r=0;r<n.length;r++){const a=n[r];if(!a||a<=0)continue;const c=w(a);if(!c)continue;const d=new i.Sprite(c);d.x=o+r*p,d.y=s+e*m,d.width=y,d.height=v,null!=l&&(d.tint=l),t.addChild(d)}}e.root.addChild(t),e.layerContainers.push(t)}}loadV2Tileset(t){var n,i;return r(this,void 0,void 0,function*(){if(!t.tilemapRef)return null;const o=yield e.resource.getResource(t.tilemapRef);if(!o)return null;const s=null!==(n=o.instance)&&void 0!==n?n:null===(i=o.data)||void 0===i?void 0:i.json;return s&&"tileset"===s.kind?f(s):("undefined"!=typeof console&&console.error(`[Tilemap] resource '${t.tilemapRef}' is not a TileSet document`),null)})}loadAtlasTextures(t,n){return r(this,void 0,void 0,function*(){const i=new Set;for(const e of n.sourcesBySlot)"atlas"===e.kind&&e.textureAsset&&i.add(e.textureAsset);yield Promise.all(Array.from(i).map(n=>r(this,void 0,void 0,function*(){var i,o,s;try{const r=yield e.resource.getResource(n),l=null!==(s=null!==(i=null==r?void 0:r.instance)&&void 0!==i?i:null===(o=null==r?void 0:r.data)||void 0===o?void 0:o.image)&&void 0!==s?s:null;l&&t.atlasTextures.set(n,l)}catch(e){"undefined"!=typeof console&&console.warn(`[Tilemap] failed to load atlas asset '${n}'`,e)}})))})}tearDownChildrenV2(e){for(const{container:t}of e.layerContainersV2.values())e.root.removeChild(t),t.destroy({children:!0});e.layerContainersV2.clear();for(const t of e.frameTexturesV2.values())try{t.destroy(!1)}catch(e){}e.frameTexturesV2.clear(),e.animatedSpritesByAnimKey.clear()}buildLayersV2(e,t,n){var o,s,r,l,a,c,d,u,h,f,p;const m=e.loadedTileset;if(!m)return;const y=null!==(s=null===(o=t.cellSize)||void 0===o?void 0:o.width)&&void 0!==s?s:m.tileWidth,v=null!==(l=null===(r=t.cellSize)||void 0===r?void 0:r.height)&&void 0!==l?l:m.tileHeight,g=null!==(c=null===(a=t.mapOrigin)||void 0===a?void 0:a.x)&&void 0!==c?c:0,C=null!==(u=null===(d=t.mapOrigin)||void 0===d?void 0:d.y)&&void 0!==u?u:0,T=(null!==(h=t.layersV2)&&void 0!==h?h:[]).map((e,t)=>({layer:e,idx:t})).sort((e,t)=>{var n,i;return(null!==(n=e.layer.zIndex)&&void 0!==n?n:0)-(null!==(i=t.layer.zIndex)&&void 0!==i?i:0)});for(const{layer:t}of T){if(!1===t.enabled)continue;const o=new i.Container;o.label=null!==(f=t.name)&&void 0!==f?f:t.id,o.alpha=null!==(p=t.opacity)&&void 0!==p?p:1,o.visible=!1!==t.visible;const s=new Map;this.buildChunksForLayer(e,o,s,t,m,y,v,g,C,n),e.root.addChild(o),e.layerContainersV2.set(t.id,{container:o,chunkContainers:s})}}buildChunksForLayer(e,t,n,o,s,r,l,c,h,f){var p;const m=o.cellData;if(!m||!m.chunks)return;const v=Object.entries(m.chunks).filter(([,e])=>e&&e.nonEmpty>0),g=v.length,T=null!==(p=e.cullingBoundsHint)&&void 0!==p?p:null;let x=0;this.probeBegin(y.CULL_CHECK_MS);for(const[p,m]of v){if(T){const e=p.split(","),t=Number.parseInt(e[0],10),n=Number.parseInt(e[1],10),i=c+t*a*r,o=h+n*a*l,s=o+a*l;if(!(i+a*r>T.minX&&i<T.maxX&&s>T.minY&&o<T.maxY)){x++;continue}}const v=new i.Container;v.label=`chunk-${p}`;let b=1,S=null;try{S=u(m);const e=new Set;for(let t=0;t<S.length;t++){const n=S[t];if(d(n))continue;const i=255&n,o=s.sourcesBySlot[i-1];o&&"atlas"===o.kind&&e.add(i)}b=Math.max(1,e.size)}catch(e){b=1,S=null}let w="sprite";"mesh"===C({nonEmptyCellsInChunk:m.nonEmpty,atlasesInChunk:b,totalChunksVisible:g})?this.tryBuildMeshChunk(v,p,m,s,r,l,c,h,o)?w="mesh":(w="meshFallback",this.probeCount(y.STRATEGY_MESH_FALLBACK_COUNT,1),this.populateChunkSprites(v,p,m,e,s,r,l,c,h,o,f,S)):this.populateChunkSprites(v,p,m,e,s,r,l,c,h,o,f,S),"sprite"===w?this.probeCount(y.STRATEGY_SPRITE_COUNT,1):"mesh"===w&&this.probeCount(y.STRATEGY_MESH_COUNT,1),t.addChild(v),n.set(p,v)}this.probeEnd(y.CULL_CHECK_MS),x>0&&this.probeCount(y.CULL_HITS_COUNT,x)}tryBuildMeshChunk(e,t,n,i,o,s,r,l,a){return!1}populateChunkSprites(e,t,n,o,s,r,l,h,f,p,m,v){let g;if(v)g=v;else try{g=u(n)}catch(e){return void("undefined"!=typeof console&&console.warn(`[Tilemap] chunk decode failed for ${t}`,e))}const C=t.split(","),T=Number.parseInt(C[0],10),x=Number.parseInt(C[1],10),b=T*a,S=x*a,w=function(e){if(!e)return;const t=/^#?([0-9a-fA-F]{6})(?:[0-9a-fA-F]{2})?$/.exec(e);return t?parseInt(t[1],16):void 0}(p.modulate);let I=0;for(let t=0;t<a;t++)for(let n=0;n<a;n++){const u=g[t*a+n];if(d(u))continue;const p=c(u),y=this.getAtlasFrameTexture(o,s,p);if(!y)continue;const v=new i.Sprite(y);if(I++,v.x=h+(b+n)*r,v.y=f+(S+t)*l,v.width=r,v.height=l,p.flipH&&(v.scale.x=-Math.abs(v.scale.x||1)),p.flipV&&(v.scale.y=-Math.abs(v.scale.y||1)),p.transpose&&(v.rotation=Math.PI/2),p.flipH&&(v.x+=r),p.flipV&&(v.y+=l),null!=w&&(v.tint=w),e.addChild(v),m&&m.isAnimatedSource(p.sourceSlot,p.col,p.row)){const e=`${p.sourceSlot},${p.col},${p.row}`;let t=o.animatedSpritesByAnimKey.get(e);t||(t=[],o.animatedSpritesByAnimKey.set(e,t)),t.push(v)}}I>0&&this.probeCount(y.DRAWCALLS_COUNT,I)}getAtlasFrameTexture(e,t,n){var o,s,r,l;const a=t.sourcesBySlot[n.sourceSlot-1];if(!a)return null;if("atlas"!==a.kind)return"sceneCollection"===a.kind&&(this.probeCount(y.SCENECOLLECTION_SKIPPED_COUNT,1),e.sceneCollectionWarnedSourceIds.has(a.id)||(e.sceneCollectionWarnedSourceIds.add(a.id),"undefined"!=typeof console&&console.warn(`[Tilemap] sceneCollection source '${a.id}' cells are not yet rendered (prefab instantiation pending). Skipped cell at slot=${n.sourceSlot} col=${n.col} row=${n.row}.`))),null;const c=e.atlasTextures.get(a.textureAsset);if(!c)return null;const d=null!==(o=a.margins)&&void 0!==o?o:{x:0,y:0},u=null!==(s=a.separation)&&void 0!==s?s:{x:0,y:0},h=a.regionSize.width,f=a.regionSize.height,p=`${a.textureAsset}#${h}x${f}|${d.x},${d.y}|${u.x},${u.y}#${n.col},${n.row}`,m=e.frameTexturesV2.get(p);if(m)return m;const v=d.x+n.col*(h+u.x),g=d.y+n.row*(f+u.y);try{const t=null!==(l=null!==(r=c.source)&&void 0!==r?r:c.baseTexture)&&void 0!==l?l:c,n=new i.Texture({source:t,frame:new i.Rectangle(v,g,h,f)});return e.frameTexturesV2.set(p,n),n}catch(e){return"undefined"!=typeof console&&console.warn(`[Tilemap] frame slice failed for ${p}`,e),null}}destroy(){var e;for(const t in this.records){const n=parseInt(t),i=this.records[n];this.tearDownChildrenV1(i),this.tearDownChildrenV2(i);const o=null===(e=this.containerManager)||void 0===e?void 0:e.getContainer(n);o&&o.removeChild(i.root),i.root.destroy({children:!0}),delete this.records[n]}this.uninstallVisibilityHandlers()}};T.systemName="Tilemap",T=o([e.decorators.componentObserver({Tilemap:[{prop:["tileset"],deep:!1},{prop:["tilemapRef"],deep:!1},{prop:["layersV2"],deep:!1}]})],T);var x=T;const b=["topLeft","top","topRight","right","bottomRight","bottom","bottomLeft","left"];function S(e){var t;let n=0;for(let i=0;i<8;i++){n|=(15&(null!==(t=e[i])&&void 0!==t?t:15))<<4*i}return n>>>0}function w(e,t){return e>>>4*t&15}const I="#version 300 es\nprecision highp float;\n\nin vec2 aPosition;\nin vec2 aTexCoord;\nin vec4 aFlags;\n\nuniform mat3 uProjectionMatrix;\nuniform mat3 uWorldTransformMatrix;\n\nout vec2 vTexCoord;\n\nvoid main() {\n vec3 worldPos = uWorldTransformMatrix * vec3(aPosition, 1.0);\n gl_Position = vec4((uProjectionMatrix * worldPos).xy, 0.0, 1.0);\n\n vec2 uv = aTexCoord;\n if (aFlags.x > 0.5) uv.x = 1.0 - uv.x;\n if (aFlags.y > 0.5) uv.y = 1.0 - uv.y;\n if (aFlags.z > 0.5) { float t = uv.x; uv.x = uv.y; uv.y = t; }\n vTexCoord = uv;\n}\n",_="#version 300 es\nprecision highp float;\n\nin vec2 vTexCoord;\nout vec4 fragColor;\n\nuniform sampler2D uTexture;\nuniform vec4 uModulate;\n\nvoid main() {\n vec4 sampled = texture(uTexture, vTexCoord);\n fragColor = sampled * uModulate;\n if (fragColor.a < 0.01) discard;\n}\n",E={vertex:I,fragment:_},A=16;function R(e,t){const n=new Map,i=new Map;for(const t of e.sources)n.set(t.id,t);for(const e of t.sources)i.set(e.id,e);const o=[],s=[],r=[];for(const e of i.keys())n.has(e)?JSON.stringify(n.get(e))!==JSON.stringify(i.get(e))&&r.push(e):o.push(i.get(e));for(const e of n.keys())i.has(e)||s.push(e);const l=new Set,a=new Set,c=new Set,d=e=>{const t=new Map;if("atlas"!==e.kind)return t;for(const n of e.tiles)t.set(`${e.id}/${n.atlasCoords.col},${n.atlasCoords.row}`,n);return t};for(const[e,t]of i){const i=n.get(e);if(!i){const e=d(t);for(const t of e.keys())l.add(t);continue}const o=d(i),s=d(t);for(const e of s.keys())o.has(e)?JSON.stringify(o.get(e))!==JSON.stringify(s.get(e))&&c.add(e):l.add(e);for(const e of o.keys())s.has(e)||a.add(e)}for(const e of s){const t=d(n.get(e));for(const e of t.keys())a.add(e)}return{addedSources:o,removedSourceIds:s,changedSourceIds:r,addedTilesByKey:l,removedTilesByKey:a,changedTilesByKey:c}}const M=R;function L(e){return`${e.sourceSlot},${e.col},${e.row},${e.altIdx},${e.layerId}`}class O{constructor(e=1e3){this.cache=new Map,this.accessOrder=new Map,this.accessCounter=0,this.maxEntries=e}get(e){const t=L(e),n=this.cache.get(t);return n&&this.accessOrder.set(t,++this.accessCounter),n}set(e,t){const n=L(e);this.cache.set(n,t),this.accessOrder.set(n,++this.accessCounter),this.cache.size>this.maxEntries&&this.evictLRU()}has(e){return this.cache.has(L(e))}clear(){this.cache.clear(),this.accessOrder.clear(),this.accessCounter=0}get size(){return this.cache.size}evictLRU(){let e,t=1/0;for(const[n,i]of this.accessOrder)i<t&&(t=i,e=n);e&&(this.cache.delete(e),this.accessOrder.delete(e))}}function k(e,t,n){return e.map(e=>({vertices:e.vertices.map(e=>({x:e.x+t,y:e.y+n}))}))}function D(e){if(e.length<3)return[];if(!function(e){if(e.length<3)return!0;let t=0;const n=e.length;for(let i=0;i<n;i++){const o=e[i],s=e[(i+1)%n],r=e[(i+2)%n],l=s.x-o.x,a=s.y-o.y,c=r.x-s.x,d=l*(r.y-s.y)-a*c;if(0!==d)if(0===t)t=d>0?1:-1;else if((d>0?1:-1)!==t)return!1}return!0}(e)){const t=new Error(`decomposePolygon: input polygon (${e.length} vertices) is non-convex. This is a placeholder implementation that assumes convex input — concave polygons silently produce invalid Matter.js bodies. Real concave decomposition requires the 'poly-decomp' npm dependency (see ADR-0019 Phase 1). If you need concave physics tiles right now, split into convex parts manually.`);throw"undefined"!=typeof console&&console.error("[Tilemap]",t.message),t}return[{vertices:e.slice()}]}function N(e,t,n,i){return((255&e)<<24|(63&i)<<18|(511&n)<<9|511&t)>>>0}O.prototype.getNum=function(e){return this.get({sourceSlot:e>>>24&255,altIdx:e>>>18&63,row:e>>>9&511,col:511&e,layerId:"__num__"})},O.prototype.setNum=function(e,t){this.set({sourceSlot:e>>>24&255,altIdx:e>>>18&63,row:e>>>9&511,col:511&e,layerId:"__num__"},t)};const B=new class{constructor(){this.builders=new Map}register(e,t){this.builders.set(e,t)}unregister(e){this.builders.delete(e)}has(e){return this.builders.has(e)}build(e,t){const n=this.builders.get(e);return n?n(t):null}listRegisteredNames(){return Array.from(this.builders.keys())}clear(){this.builders.clear()}};function V(e){return 255&e}function $(e){return e>>>8&255}function P(e){return e>>>16&255}function H(e){return e>>>24&31}function K(e,t){var n;const i=[];for(const[o,s]of Object.entries(e.chunksByKey)){const[r,l]=o.split(","),a=Number.parseInt(r,10),c=Number.parseInt(l,10);if(Number.isFinite(a)&&Number.isFinite(c))for(let r=0;r<16;r++)for(let l=0;l<16;l++){const d=s[16*r+l],u=V(d);if(0===u)continue;const h=$(d),f=P(d),p=H(d),m=`${u},${h},${f},${p}`,y=e.physicsByCellKey.get(m);if(!y||0===y.length)continue;const v=e.mapOriginX+(16*a+l)*e.cellWidth+t.worldX,g=e.mapOriginY+(16*c+r)*e.cellHeight+t.worldY;for(const t of y)for(const s of t.polygons){const a=N(u,h,f,p);let c=null===(n=e.cache.getNum(a))||void 0===n?void 0:n.parts;c||(c=D(s.points),e.cache.setNum(a,{parts:c}));const d=k(c,v,g);for(let n=0;n<d.length;n++)i.push({id:`tile-${o}-${l}-${r}-${t.layerId}-${n}`,vertices:d[n].vertices,centerX:v+e.cellWidth/2,centerY:g+e.cellHeight/2,isStatic:!0,oneWay:t.oneWay,friction:t.friction,restitution:t.restitution,metadata:{layerId:t.layerId,chunkKey:o,cellLocal:[l,r]}})}}}return i}try{e.resource.registerResourceType("TILESET")}catch(e){}try{e.resource.registerInstance("TILESET",e=>{var t,n,i,o;const s=null===(t=e.data)||void 0===t?void 0:t.json,r=null===(i=null===(n=e.src)||void 0===n?void 0:n.json)||void 0===i?void 0:i.data;return null!==(o=null!=s?s:r)&&void 0!==o?o:null})}catch(e){}exports.ADR_0019_NATIVE_REGISTRY_AVAILABLE=!1,exports.CHUNK_SIZE=a,exports.DecompositionCache=O,exports.MAX_TERRAIN_ID=14,exports.NEIGHBOR_DIRECTIONS=b,exports.NO_NEIGHBOR=15,exports.PeeringBitIndex=class{constructor(e){this.terrainSetIndex=e,this.exact=new Map,this.wildcards=[]}add(e,t){var n;const i=[],o=[];for(let e=0;e<8;e++){const n=null==t?void 0:t[b[e]];void 0===n?(i.push(15),o.push(0)):(i.push(15&n),o.push(15))}const s=S(i),r=S(o);if(o.every(e=>15===e)){const t=null!==(n=this.exact.get(s))&&void 0!==n?n:[];t.push(e),this.exact.set(s,t)}else this.wildcards.push({key:s,mask:r,candidate:e})}match(e){const t=S(e),n=this.exact.get(t);if(n&&n.length>0)return{candidates:n.slice(),exactMatch:!0,bestHammingDistance:0};let i=1/0,o=[];for(const{key:e,mask:n,candidate:s}of this.wildcards){let r=0,l=!0;for(let o=0;o<8;o++){if(0===w(n,o))continue;if(w(t,o)!==w(e,o)&&(r++,r>i)){l=!1;break}}l&&(r<i?(i=r,o=[s]):r===i&&o.push(s))}return{candidates:o,exactMatch:!1,bestHammingDistance:i===1/0?-1:i}}get exactBucketCount(){return this.exact.size}get wildcardCount(){return this.wildcards.length}},exports.TILEMAP_BODY_SOURCE_REGISTRY=B,exports.TILEMAP_PROBE_NAMES=y,exports.TILE_FRAG_SHADER=_,exports.TILE_SHADER_SOURCES=E,exports.TILE_VERT_SHADER=I,exports.TileAnimationDriver=p,exports.Tilemap=l,exports.TilemapSystem=x,exports.adaptGamePerfProbes=g,exports.buildChunkGeometry=function(e){const{cells:t,chunkWorldX:n,chunkWorldY:i,cellWidth:o,cellHeight:s,atlasInfo:r}=e;if(256!==t.length)throw new Error(`buildChunkGeometry: cells length ${t.length} != 256`);let l=0;for(let e=0;e<t.length;e++)d(t[e])||l++;const a=new Float32Array(4*l*8),u=new Uint16Array(6*l);let h=0,f=0,p=0;for(let e=0;e<A;e++)for(let l=0;l<A;l++){const m=t[e*A+l];if(d(m))continue;const y=c(m),v=n+l*o,g=i+e*s,C=v+o,T=g+s,x=(r.margins.x+y.col*(r.regionWidth+r.separation.x))/r.textureWidth,b=x+r.regionWidth/r.textureWidth,S=(r.margins.y+y.row*(r.regionHeight+r.separation.y))/r.textureHeight,w=S+r.regionHeight/r.textureHeight,I=y.flipH?1:0,_=y.flipV?1:0,E=y.transpose?1:0,R=0,M=(e,t,n,i)=>{a[h++]=e,a[h++]=t,a[h++]=n,a[h++]=i,a[h++]=I,a[h++]=_,a[h++]=E,a[h++]=R};M(v,g,x,S),M(C,g,b,S),M(C,T,b,w),M(v,T,x,w);const L=4*p;u[f++]=L,u[f++]=L+1,u[f++]=L+2,u[f++]=L,u[f++]=L+2,u[f++]=L+3,p++}return{vertexData:a,indices:u,quadCount:p}},exports.buildChunkMesh=function(e){const t=new i.Container;return t.label=`chunk-mesh-stub-${e.chunkKey}`,t},exports.buildTileMapStaticBodies=K,exports.buildTileMapStaticBodyDefinitions=function(e,t,n){var i,o;let s;null==n||n.beginTiming(y.PHYSICS_REBAKE_MS);try{s=K(e,t)}finally{null==n||n.endTiming(y.PHYSICS_REBAKE_MS)}const r=new Map;for(const e of s){const t=null!==(o=null===(i=e.metadata)||void 0===i?void 0:i.layerId)&&void 0!==o?o:"<unlabeled>";let n=r.get(t);n||(n=[],r.set(t,n)),n.push(e)}const l=s.length;return null==n||n.gauge(y.BODIES_TOTAL,l),l>0&&(null==n||n.count(y.BODIES_CREATED,l)),{bodies:s,totalBodyCount:l,bodiesByLayerId:r}},exports.cacheKeyOf=L,exports.cacheKeyOfNum=N,exports.computeAffectedChunks=function(e,t,n){const i=new Set,o=(e,i,o)=>{const s=t.get(e);if(!s)return!1;const r=`${s}/${i},${o}`;return n.changedTilesByKey.has(r)||n.removedTilesByKey.has(r)||n.addedTilesByKey.has(r)};for(const[t,n]of Object.entries(e))for(let e=0;e<n.length;e++){const s=n[e],r=255&s;if(0===r)continue;if(o(r,s>>>8&255,s>>>16&255)){i.add(t);break}}return i},exports.createInMemoryProbeRegistry=function(){const e=new Map,t=new Map,n=new Map,i=new Map;return{beginTiming(t){e.set(t,v())},endTiming(n){const i=e.get(n);if(void 0===i)return;e.delete(n);const o=v()-i;t.has(n)||t.set(n,[]),t.get(n).push(o)},count(e,t=1){var i;n.set(e,(null!==(i=n.get(e))&&void 0!==i?i:0)+t)},gauge(e,t){i.set(e,t)},histogram(e,t){this.count(`${e}.histN`),this.count(`${e}.histSum`,t)},timings:t,counts:n,gauges:i}},exports.decodeChunk=u,exports.decomposePolygon=D,exports.diffTilesetDocuments=M,exports.diffTilesetForChunkRebuild=R,exports.estimateChunkMeshMemoryKB=function(e){return Math.ceil(11)},exports.estimateSpriteNodes=function(e){return 1+e},exports.expandSceneCollectionSource=function(e){return"sceneCollection"!==e.kind?[]:e.prefabRefs.map((t,n)=>({sourceId:e.id,prefabName:t,index:n}))},exports.extractPhysicsByCellKey=function(e){const t=new Map;for(let n=0;n<e.sources.length;n++){const i=e.sources[n];if(!i||"atlas"!==i.kind||!i.tiles)continue;const o=n+1;for(const e of i.tiles){const{col:n,row:i}=e.atlasCoords;for(const s of e.alternatives){if(!s.physics||0===s.physics.length)continue;const e=`${o},${n},${i},${31&s.altId}`;t.set(e,s.physics)}}}return t},exports.getRequiredTilemapProbes=function(){return Object.values(y)},exports.isEmptyCellValue=d,exports.isMeshPathAvailable=function(){return!1},exports.makeLoadedTileset=f,exports.pickAutotileCandidate=function(e,t){if(0===e.length)return null;if(1===e.length)return e[0];const n=e.reduce((e,t)=>e+(t.probability>0?t.probability:1),0),i=t()*n;let o=0;for(const t of e)if(o+=t.probability>0?t.probability:1,i<o)return t;return e[e.length-1]},exports.resolveCellPrefabName=function(e,t){var n;const i=255&e;if(0===i)return null;const o=t[i-1];if(!o||"sceneCollection"!==o.kind)return null;const s=e>>>8&255;return null!==(n=o.prefabRefs[s])&&void 0!==n?n:null},exports.resolveChunkRenderStrategy=C,exports.translateConvexParts=k,exports.unpackCell=c;
|
|
@@ -771,13 +771,14 @@ let TilemapSystem = class TilemapSystem extends Renderer {
|
|
|
771
771
|
// chunkContainer,destroy + 重新调 populateChunkSprites。需要拿到 layer 配置(cellData/modulate
|
|
772
772
|
// /opacity)— 通过遍历 record.layerContainersV2 找到 chunkContainers 即可。但要 populate 还需
|
|
773
773
|
// cellData.chunks[chunkKey] — 必须找 component。
|
|
774
|
-
const game = this
|
|
774
|
+
const game = this
|
|
775
|
+
.game;
|
|
775
776
|
let component = null;
|
|
776
777
|
if (game === null || game === void 0 ? void 0 : game.gameObjects) {
|
|
777
778
|
for (const go of game.gameObjects) {
|
|
778
779
|
if (go.id !== gameObjectId)
|
|
779
780
|
continue;
|
|
780
|
-
const c = (_b = go.components) === null || _b === void 0 ? void 0 : _b.find(
|
|
781
|
+
const c = (_b = go.components) === null || _b === void 0 ? void 0 : _b.find(cc => (cc === null || cc === void 0 ? void 0 : cc.name) === 'Tilemap');
|
|
781
782
|
if (c) {
|
|
782
783
|
component = c;
|
|
783
784
|
break;
|
|
@@ -795,7 +796,7 @@ let TilemapSystem = class TilemapSystem extends Renderer {
|
|
|
795
796
|
if (!layerEntry)
|
|
796
797
|
continue;
|
|
797
798
|
// 找 layer 配置(modulate/opacity/cellData)— 必须从 component.layersV2 找。
|
|
798
|
-
const layerSpec = (_m = (_l = component === null || component === void 0 ? void 0 : component.layersV2) === null || _l === void 0 ? void 0 : _l.find(
|
|
799
|
+
const layerSpec = (_m = (_l = component === null || component === void 0 ? void 0 : component.layersV2) === null || _l === void 0 ? void 0 : _l.find(l => l.id === layerId)) !== null && _m !== void 0 ? _m : null;
|
|
799
800
|
if (!layerSpec)
|
|
800
801
|
continue;
|
|
801
802
|
for (const chunkKey of chunkKeys) {
|
|
@@ -865,6 +866,12 @@ let TilemapSystem = class TilemapSystem extends Renderer {
|
|
|
865
866
|
* 期间渲染调用堆栈抛错。
|
|
866
867
|
*/
|
|
867
868
|
update(_frame) {
|
|
869
|
+
// Renderer.update owns ComponentObserver flushing. Tilemap also needs a
|
|
870
|
+
// per-frame animation tick, but overriding update without delegating to
|
|
871
|
+
// the base class strands every ADD/CHANGE/REMOVE event in the queue and
|
|
872
|
+
// leaves the scene component permanently disconnected from its record.
|
|
873
|
+
// Lifecycle changes must still flush while animation work is paused.
|
|
874
|
+
super.update(_frame);
|
|
868
875
|
// T-N2:tab 切换到后台 / WebGL context 异常 → 暂停 tick。
|
|
869
876
|
if (this.isHidden || this.contextLost)
|
|
870
877
|
return;
|
|
@@ -873,7 +880,7 @@ let TilemapSystem = class TilemapSystem extends Renderer {
|
|
|
873
880
|
this.probeBegin(TILEMAP_PROBE_NAMES.ANIM_TICK_MS);
|
|
874
881
|
let totalSpritesSwapped = 0;
|
|
875
882
|
try {
|
|
876
|
-
const now =
|
|
883
|
+
const now = typeof performance !== 'undefined' && performance.now ? performance.now() : 0;
|
|
877
884
|
// PERF-T-O2 (see ADR-0022): consider flattening dirty (sprite, texture) pairs into a typed
|
|
878
885
|
// array once per record when animatedSpritesByAnimKey changes. Trigger: >1000 animated cells
|
|
879
886
|
// + p99(animTick.ms) > 2ms. Defer until probe data warrants.
|
|
@@ -943,7 +950,16 @@ let TilemapSystem = class TilemapSystem extends Renderer {
|
|
|
943
950
|
yield this.handleAdd(gameObjectId, changed.gameObject, component);
|
|
944
951
|
}
|
|
945
952
|
else if (changed.type === OBSERVER_TYPE.CHANGE) {
|
|
946
|
-
|
|
953
|
+
// Editor initial reconciliation can coalesce an unflushed ADD/REMOVE pair
|
|
954
|
+
// and leave only CHANGE events for the live replacement component. A
|
|
955
|
+
// renderer must recover from that observer sequence or the live component
|
|
956
|
+
// remains disconnected from its runtime record.
|
|
957
|
+
if (!this.records[gameObjectId]) {
|
|
958
|
+
yield this.handleAdd(gameObjectId, changed.gameObject, component);
|
|
959
|
+
}
|
|
960
|
+
else {
|
|
961
|
+
yield this.handleChange(gameObjectId, component, changed);
|
|
962
|
+
}
|
|
947
963
|
}
|
|
948
964
|
else if (changed.type === OBSERVER_TYPE.REMOVE) {
|
|
949
965
|
this.handleRemove(gameObjectId);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eva/plugin-renderer-tilemap",
|
|
3
|
-
"version": "2.1.0-beta.
|
|
3
|
+
"version": "2.1.0-beta.13",
|
|
4
4
|
"description": "@eva/plugin-renderer-tilemap",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "dist/plugin-renderer-tilemap.esm.js",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"homepage": "https://eva.js.org",
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@eva/inspector-decorator": "^2.0.0-beta.0",
|
|
27
|
-
"@eva/eva.js": "2.1.0-beta.
|
|
28
|
-
"@eva/plugin-renderer": "2.1.0-beta.
|
|
27
|
+
"@eva/eva.js": "2.1.0-beta.13",
|
|
28
|
+
"@eva/plugin-renderer": "2.1.0-beta.13",
|
|
29
29
|
"pixi.js": "^8.6.3"
|
|
30
30
|
}
|
|
31
31
|
}
|