diff --git a/dist/pixi-tilemap.umd.js b/dist/pixi-tilemap.umd.js index 99b8393..8e8c68d 100644 --- a/dist/pixi-tilemap.umd.js +++ b/dist/pixi-tilemap.umd.js @@ -1,8 +1,8 @@ /* eslint-disable */ /*! - * @pixi/tilemap - v2.2.0 - * Compiled Thu, 01 Apr 2021 01:53:50 UTC + * @pixi/tilemap - v3.1.0 + * Compiled Tue, 06 Apr 2021 14:12:07 UTC * * @pixi/tilemap is licensed under the MIT License. * http://www.opensource.org/licenses/mit-license @@ -206,7 +206,7 @@ this.PIXI.tilemap = this.PIXI.tilemap || {}; */ constructor(tileset) { - super();Tilemap.prototype.__init.call(this);Tilemap.prototype.__init2.call(this);Tilemap.prototype.__init3.call(this);Tilemap.prototype.__init4.call(this);Tilemap.prototype.__init5.call(this);Tilemap.prototype.__init6.call(this);Tilemap.prototype.__init7.call(this);Tilemap.prototype.__init8.call(this);Tilemap.prototype.__init9.call(this);Tilemap.prototype.__init10.call(this);Tilemap.prototype.__init11.call(this);Tilemap.prototype.__init12.call(this);Tilemap.prototype.__init13.call(this);Tilemap.prototype.__init14.call(this);Tilemap.prototype.__init15.call(this);; + super();Tilemap.prototype.__init.call(this);Tilemap.prototype.__init2.call(this);Tilemap.prototype.__init3.call(this);Tilemap.prototype.__init4.call(this);Tilemap.prototype.__init5.call(this);Tilemap.prototype.__init6.call(this);Tilemap.prototype.__init7.call(this);Tilemap.prototype.__init8.call(this);Tilemap.prototype.__init9.call(this);Tilemap.prototype.__init10.call(this);Tilemap.prototype.__init11.call(this);Tilemap.prototype.__init12.call(this);Tilemap.prototype.__init13.call(this);Tilemap.prototype.__init14.call(this);Tilemap.prototype.__init15.call(this);Tilemap.prototype.__init16.call(this);; this.setTileset(tileset); } @@ -414,7 +414,7 @@ this.PIXI.tilemap = this.PIXI.tilemap || {}; pb[pb.length - (POINT_STRUCT_SIZE - POINT_STRUCT.ALPHA)] = alpha; } - renderCanvas(renderer) + __init11() {this.renderCanvas = (renderer) => { const plugin = renderer.plugins.tilemap; @@ -433,7 +433,7 @@ this.PIXI.tilemap = this.PIXI.tilemap || {}; } this.renderCanvasCore(renderer); - } + };} renderCanvasCore(renderer) { @@ -476,11 +476,11 @@ this.PIXI.tilemap = this.PIXI.tilemap || {}; } } - __init11() {this.vbId = 0;} - __init12() {this.vb = null;} - __init13() {this.vbBuffer = null;} - __init14() {this.vbArray = null;} - __init15() {this.vbInts = null;} + __init12() {this.vbId = 0;} + __init13() {this.vb = null;} + __init14() {this.vbBuffer = null;} + __init15() {this.vbArray = null;} + __init16() {this.vbInts = null;} destroyVb() { @@ -916,7 +916,7 @@ this.PIXI.tilemap = this.PIXI.tilemap || {}; */ constructor(tileset) { - super();CompositeTilemap.prototype.__init.call(this);CompositeTilemap.prototype.__init2.call(this);CompositeTilemap.prototype.__init3.call(this);CompositeTilemap.prototype.__init4.call(this);CompositeTilemap.prototype.__init5.call(this);CompositeTilemap.prototype.__init6.call(this);; + super();CompositeTilemap.prototype.__init.call(this);CompositeTilemap.prototype.__init2.call(this);CompositeTilemap.prototype.__init3.call(this);CompositeTilemap.prototype.__init4.call(this);CompositeTilemap.prototype.__init5.call(this);CompositeTilemap.prototype.__init6.call(this);CompositeTilemap.prototype.__init7.call(this);; this.tileset(tileset); this.texturesPerTilemap = settings.TEXTURES_PER_TILEMAP; @@ -1151,7 +1151,7 @@ this.PIXI.tilemap = this.PIXI.tilemap || {}; return this; } - renderCanvas(renderer) + __init6() {this.renderCanvas = (renderer) => { if (!this.visible || this.worldAlpha <= 0 || !this.renderable) { @@ -1183,7 +1183,7 @@ this.PIXI.tilemap = this.PIXI.tilemap || {}; layer.tileAnim = this.tileAnim; layer.renderCanvasCore(renderer); } - } + };} render(renderer) { @@ -1322,7 +1322,7 @@ this.PIXI.tilemap = this.PIXI.tilemap || {}; * * @deprecated Since @pixi/tilemap 3. */ - __init6() {this.setBitmaps = this.tileset;} + __init7() {this.setBitmaps = this.tileset;} /** * @deprecated Since @pixi/tilemap 3. diff --git a/dist/pixi-tilemap.umd.js.map b/dist/pixi-tilemap.umd.js.map index 7484562..185902f 100644 --- a/dist/pixi-tilemap.umd.js.map +++ b/dist/pixi-tilemap.umd.js.map @@ -1 +1 @@ -{"version":3,"file":"pixi-tilemap.umd.js","sources":["../src/CanvasTileRenderer.ts","../src/settings.ts","../src/Tilemap.ts","../src/CompositeTilemap.ts","../src/TextileResource.ts","../src/shaderGenerator.ts","../src/TilemapShader.ts","../src/TileRenderer.ts","../src/index.ts"],"sourcesContent":["import type { AbstractRenderer } from '@pixi/core';\n\n/**\n * The renderer plugin for canvas. It isn't registered by default.\n *\n * ```\n * import { CanvasTileRenderer } from '@pixi/tilemap';\n * import { CanvasRenderer } from '@pixi/canvas-core';\n *\n * // You must register this yourself (optional). @pixi/tilemap doesn't do it to\n * // prevent a hard dependency on @pixi/canvas-core.\n * CanvasRenderer.registerPlugin('tilemap', CanvasTileRenderer);\n * ```\n */\n// TODO: Move to @pixi/tilemap-canvas\nexport class CanvasTileRenderer\n{\n /** The renderer */\n renderer: AbstractRenderer;\n\n /** The global tile animation state */\n tileAnim = [0, 0];\n\n /** @deprecated */\n dontUseTransform = false;\n\n /** @param renderer */\n constructor(renderer: AbstractRenderer)\n {\n this.renderer = renderer;\n this.tileAnim = [0, 0];\n }\n}\n","import { SCALE_MODES } from '@pixi/constants';\n\n/**\n * These are additional @pixi/tilemap options.\n *\n * This settings should not be changed after the renderer has initialized; otherwise, the behavior\n * is undefined.\n */\nexport const settings = {\n /** The default number of textures per tilemap in a tilemap composite. */\n TEXTURES_PER_TILEMAP: 16,\n\n /**\n * The width/height of each texture tile in a {@link TEXTILE_DIMEN}. This is 1024px by default.\n *\n * This should fit all tile base-textures; otherwise, {@link TextileResource} may fail to correctly\n * upload the textures togther in a tiled fashion.\n */\n TEXTILE_DIMEN: 1024,\n\n /**\n * The number of texture tiles per {@link TextileResource}.\n *\n * Texture tiling is disabled by default, and so this is set to `1` by default. If it is set to a\n * higher value, textures will be uploaded together in a tiled fashion.\n *\n * Since {@link TextileResource} is a dual-column format, this should be even for packing\n * efficiency. The optimal value is usually 4.\n */\n TEXTILE_UNITS: 1,\n\n /** The scaling mode of the combined texture tiling. */\n TEXTILE_SCALE_MODE: SCALE_MODES.LINEAR,\n\n /** This will enable 32-bit index buffers. It's useful when you have more than 16K tiles. */\n use32bitIndex: false,\n\n /** Flags whether textiles should be cleared when each tile is uploaded. */\n DO_CLEAR: true,\n\n // Backward compatibility\n get maxTextures(): number { return this.MAX_TEXTURES; },\n set maxTextures(value: number) { this.MAX_TEXTURES = value; },\n\n get boundSize(): number { return this.TEXTURE_TILE_DIMEN; },\n set boundSize(value: number) { this.TILE_TEXTURE_DIMEN = value; },\n\n get boundCountPerBuffer(): number { return this.TEXTILE_UNITS; },\n set boundCountPerBuffer(value: number) { this.TEXTILE_UNITS = value; },\n};\n\n// @deprecated\nexport const Constant = settings;\n","import { Container, Bounds } from '@pixi/display';\nimport { DRAW_MODES } from '@pixi/constants';\nimport { Texture, Renderer } from '@pixi/core';\nimport { TileRenderer } from './TileRenderer';\nimport { Matrix, Rectangle, groupD8 } from '@pixi/math';\nimport { settings } from './settings';\n\nimport type { BaseTexture } from '@pixi/core';\nimport type { CanvasRenderer } from '@pixi/canvas-renderer';\nimport type { IDestroyOptions } from '@pixi/display';\nimport type { TilemapGeometry } from './TilemapShader';\n\nenum POINT_STRUCT {\n U = 0,\n V,\n X,\n Y,\n TILE_WIDTH,\n TILE_HEIGHT,\n ROTATE,\n ANIM_X,\n ANIM_Y,\n TEXTURE_INDEX,\n ANIM_COUNT_X,\n ANIM_COUNT_Y,\n ALPHA,\n}\n\nexport const POINT_STRUCT_SIZE = (Object.keys(POINT_STRUCT).length / 2);\n\n/**\n * A rectangular tilemap implementation that renders a predefined set of tile textures.\n *\n * The {@link Tilemap.tileset tileset} of a tilemap defines the list of base-textures that can be painted in the\n * tilemap. A texture is identified using its base-texture's index into the this list, i.e. changing the base-texture\n * at a given index in the tileset modifies the paint of all tiles pointing to that index.\n *\n * The size of the tileset is limited by the texture units supported by the client device. The minimum supported\n * value is 8, as defined by the WebGL 1 specification. `gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS`) can be used\n * to extract this limit. {@link CompositeTilemap} can be used to get around this limit by layering multiple tilemap\n * instances.\n *\n * @example\n * import { Tilemap } from '@pixi/tilemap';\n * import { Loader } from '@pixi/loaders';\n *\n * // Add the spritesheet into your loader!\n * Loader.shared.add('atlas', 'assets/atlas.json');\n *\n * // Make the tilemap once the tileset assets are available.\n * Loader.shared.load(function onTilesetLoaded()\n * {\n * // The base-texture is shared between all the tile textures.\n * const tilemap = new Tilemap([Texture.from('grass.png').baseTexture])\n * .tile('grass.png', 0, 0)\n * .tile('grass.png', 100, 100)\n * .tile('brick_wall.png', 0, 100);\n * });\n */\nexport class Tilemap extends Container\n{\n shadowColor = new Float32Array([0.0, 0.0, 0.0, 0.5]);\n _globalMat: Matrix = null;\n\n /**\n * The tile animation frame.\n *\n * @see CompositeTilemap.tileAnim\n */\n public tileAnim: [number, number] = null;\n\n /**\n * This is the last uploaded size of the tilemap geometry.\n * @ignore\n */\n modificationMarker = 0;\n\n /** @ignore */\n offsetX = 0;\n\n /** @ignore */\n offsetY = 0;\n\n /** @ignore */\n compositeParent = false;\n\n /**\n * The list of base-textures being used in the tilemap.\n *\n * This should not be shuffled after tiles have been added into this tilemap. Usually, only tile textures\n * should be added after tiles have been added into the map.\n */\n protected tileset: Array;\n\n /**\n * The local bounds of the tilemap itself. This does not include DisplayObject children.\n */\n protected readonly tilemapBounds = new Bounds();\n\n /** Flags whether any animated tile was added. */\n protected hasAnimatedTile = false;\n\n /** The interleaved geometry of the tilemap. */\n private pointsBuf: Array = [];\n\n /**\n * @param tileset - The tileset to use for the tilemap. This can be reset later with {@link Tilemap.setTileset}. The\n * base-textures in this array must not be duplicated.\n */\n constructor(tileset: BaseTexture | Array)\n {\n super();\n this.setTileset(tileset);\n }\n\n /**\n * @returns The tileset of this tilemap.\n */\n getTileset(): Array\n {\n return this.tileset;\n }\n\n /**\n * Define the tileset used by the tilemap.\n *\n * @param tileset - The list of textures to use in the tilemap. If a base-texture (not array) is passed, it will\n * be wrapped into an array. This should not contain any duplicates.\n */\n setTileset(tileset: BaseTexture | Array = []): this\n {\n if (!Array.isArray(tileset))\n {\n tileset = [tileset];\n }\n for (let i = 0; i < tileset.length; i++)\n {\n if ((tileset[i] as unknown as Texture).baseTexture)\n {\n tileset[i] = (tileset[i] as unknown as Texture).baseTexture;\n }\n }\n\n this.tileset = tileset;\n\n return this;\n }\n\n /** Clears all the tiles added into this tilemap. */\n clear(): this\n {\n this.pointsBuf.length = 0;\n this.modificationMarker = 0;\n this.tilemapBounds.clear();\n this.hasAnimatedTile = false;\n\n return this;\n }\n\n /**\n * Adds a tile that paints the given texture at (x, y).\n *\n * @param tileTexture - The tiling texture to render.\n * @param x - The local x-coordinate of the tile's position.\n * @param y - The local y-coordinate of the tile's position.\n * @param options - Additional tile options.\n * @param [options.u=texture.frame.x] - The x-coordinate of the texture in its base-texture's space.\n * @param [options.v=texture.frame.y] - The y-coordinate of the texture in its base-texture's space.\n * @param [options.tileWidth=texture.orig.width] - The local width of the tile.\n * @param [options.tileHeight=texture.orig.height] - The local height of the tile.\n * @param [options.animX=0] - For animated tiles, this is the \"offset\" along the x-axis for adjacent\n * animation frame textures in the base-texture.\n * @param [options.animY=0] - For animated tiles, this is the \"offset\" along the y-axis for adjacent\n * animation frames textures in the base-texture.\n * @param [options.rotate=0]\n * @param [options.animCountX=1024] - For animated tiles, this is the number of animation frame textures\n * per row.\n * @param [options.animCountY=1024] - For animated tiles, this is the number of animation frame textures\n * per column.\n * @param [options.alpha=1] - Tile alpha\n * @return This tilemap, good for chaining.\n */\n tile(\n tileTexture: number | string | Texture | BaseTexture,\n x: number,\n y: number,\n options: {\n u?: number,\n v?: number,\n tileWidth?: number,\n tileHeight?: number,\n animX?: number,\n animY?: number,\n rotate?: number,\n animCountX?: number,\n animCountY?: number,\n alpha?: number,\n } = {}\n ): this\n {\n let baseTexture: BaseTexture;\n let textureIndex = -1;\n\n if (typeof tileTexture === 'number')\n {\n textureIndex = tileTexture;\n baseTexture = this.tileset[textureIndex];\n }\n else\n {\n let texture: Texture | BaseTexture;\n\n if (typeof tileTexture === 'string')\n {\n texture = Texture.from(tileTexture);\n }\n else\n {\n texture = tileTexture;\n }\n\n const textureList = this.tileset;\n\n for (let i = 0; i < textureList.length; i++)\n {\n if (textureList[i] === texture.castToBaseTexture())\n {\n textureIndex = i;\n break;\n }\n }\n\n if ('baseTexture' in texture)\n {\n options.u = options.u ?? texture.frame.x;\n options.v = options.v ?? texture.frame.y;\n options.tileWidth = options.tileWidth ?? texture.orig.width;\n options.tileHeight = options.tileHeight ?? texture.orig.height;\n }\n\n baseTexture = texture.castToBaseTexture();\n }\n\n if (!baseTexture || textureIndex < 0)\n {\n console.error('The tile texture was not found in the tilemap tileset.');\n\n return this;\n }\n\n const {\n u = 0,\n v = 0,\n tileWidth = baseTexture.realWidth,\n tileHeight = baseTexture.realHeight,\n animX = 0,\n animY = 0,\n rotate = 0,\n animCountX = 1024,\n animCountY = 1024,\n alpha = 1,\n } = options;\n\n const pb = this.pointsBuf;\n\n this.hasAnimatedTile = this.hasAnimatedTile || animX > 0 || animY > 0;\n\n pb.push(u);\n pb.push(v);\n pb.push(x);\n pb.push(y);\n pb.push(tileWidth);\n pb.push(tileHeight);\n pb.push(rotate);\n pb.push(animX | 0);\n pb.push(animY | 0);\n pb.push(textureIndex);\n pb.push(animCountX);\n pb.push(animCountY);\n pb.push(alpha);\n\n this.tilemapBounds.addFramePad(x, y, x + tileWidth, y + tileHeight, 0, 0);\n\n return this;\n }\n\n /** Changes the rotation of the last tile. */\n tileRotate(rotate: number): void\n {\n const pb = this.pointsBuf;\n\n pb[pb.length - (POINT_STRUCT_SIZE - POINT_STRUCT.TEXTURE_INDEX)] = rotate;\n }\n\n /** Changes the `animX`, `animCountX` of the last tile. */\n tileAnimX(offset: number, count: number): void\n {\n const pb = this.pointsBuf;\n\n pb[pb.length - (POINT_STRUCT_SIZE - POINT_STRUCT.ANIM_X)] = offset;\n pb[pb.length - (POINT_STRUCT_SIZE - POINT_STRUCT.ANIM_COUNT_X)] = count;\n }\n\n /** Changes the `animY`, `animCountY` of the last tile. */\n tileAnimY(offset: number, count: number): void\n {\n const pb = this.pointsBuf;\n\n pb[pb.length - (POINT_STRUCT_SIZE - POINT_STRUCT.ANIM_Y)] = offset;\n pb[pb.length - (POINT_STRUCT_SIZE - POINT_STRUCT.ANIM_COUNT_Y)] = count;\n }\n\n tileAlpha(alpha: number): void\n {\n const pb = this.pointsBuf;\n\n pb[pb.length - (POINT_STRUCT_SIZE - POINT_STRUCT.ALPHA)] = alpha;\n }\n\n renderCanvas(renderer: CanvasRenderer): void\n {\n const plugin = renderer.plugins.tilemap;\n\n if (plugin && !plugin.dontUseTransform)\n {\n const wt = this.worldTransform;\n\n renderer.context.setTransform(\n wt.a,\n wt.b,\n wt.c,\n wt.d,\n wt.tx * renderer.resolution,\n wt.ty * renderer.resolution\n );\n }\n\n this.renderCanvasCore(renderer);\n }\n\n renderCanvasCore(renderer: CanvasRenderer): void\n {\n if (this.tileset.length === 0) return;\n const points = this.pointsBuf;\n const tileAnim = this.tileAnim || (renderer.plugins.tilemap && renderer.plugins.tilemap.tileAnim);\n\n renderer.context.fillStyle = '#000000';\n for (let i = 0, n = points.length; i < n; i += POINT_STRUCT_SIZE)\n {\n let x1 = points[i + POINT_STRUCT.U] * tileAnim[0];\n let y1 = points[i + POINT_STRUCT.V] * tileAnim[1];\n const x2 = points[i + POINT_STRUCT.X];\n const y2 = points[i + POINT_STRUCT.Y];\n const w = points[i + POINT_STRUCT.TILE_WIDTH];\n const h = points[i + POINT_STRUCT.TILE_HEIGHT];\n\n x1 += points[i + POINT_STRUCT.ANIM_X] * renderer.plugins.tilemap.tileAnim[0];\n y1 += points[i + POINT_STRUCT.ANIM_Y] * renderer.plugins.tilemap.tileAnim[1];\n\n const textureIndex = points[i + POINT_STRUCT.TEXTURE_INDEX];\n const alpha = points[i + POINT_STRUCT.ALPHA];\n\n // canvas does not work with rotate yet\n\n if (textureIndex >= 0 && this.tileset[textureIndex])\n {\n renderer.context.globalAlpha = alpha;\n renderer.context.drawImage(\n (this.tileset[textureIndex] as any).getDrawableSource(),\n x1, y1, w, h, x2, y2, w, h\n );\n }\n else\n {\n renderer.context.globalAlpha = 0.5;\n renderer.context.fillRect(x2, y2, w, h);\n }\n renderer.context.globalAlpha = 1;\n }\n }\n\n private vbId = 0;\n private vb: TilemapGeometry = null;\n private vbBuffer: ArrayBuffer = null;\n private vbArray: Float32Array = null;\n private vbInts: Uint32Array = null;\n\n private destroyVb(): void\n {\n if (this.vb)\n {\n this.vb.destroy();\n this.vb = null;\n }\n }\n\n render(renderer: Renderer): void\n {\n const plugin = (renderer.plugins as any).tilemap;\n const shader = plugin.getShader();\n\n renderer.batch.setObjectRenderer(plugin);\n this._globalMat = shader.uniforms.projTransMatrix;\n renderer\n .globalUniforms\n .uniforms\n .projectionMatrix\n .copyTo(this._globalMat)\n .append(this.worldTransform);\n\n shader.uniforms.shadowColor = this.shadowColor;\n shader.uniforms.animationFrame = this.tileAnim || plugin.tileAnim;\n\n this.renderWebGLCore(renderer, plugin);\n }\n\n renderWebGLCore(renderer: Renderer, plugin: TileRenderer): void\n {\n const points = this.pointsBuf;\n\n if (points.length === 0) return;\n const rectsCount = points.length / POINT_STRUCT_SIZE;\n\n const shader = plugin.getShader();\n const textures = this.tileset;\n\n if (textures.length === 0) return;\n\n plugin.bindTileTextures(renderer, textures);\n renderer.shader.bind(shader, false);\n\n // lost context! recover!\n let vb = this.vb;\n\n if (!vb)\n {\n vb = plugin.createVb();\n this.vb = vb;\n this.vbId = (vb as any).id;\n this.vbBuffer = null;\n this.modificationMarker = 0;\n }\n\n plugin.checkIndexBuffer(rectsCount, vb);\n const boundCountPerBuffer = settings.TEXTILE_UNITS;\n\n const vertexBuf = vb.getBuffer('aVertexPosition');\n // if layer was changed, re-upload vertices\n const vertices = rectsCount * vb.vertPerQuad;\n\n if (vertices === 0) return;\n if (this.modificationMarker !== vertices)\n {\n this.modificationMarker = vertices;\n const vs = vb.stride * vertices;\n\n if (!this.vbBuffer || this.vbBuffer.byteLength < vs)\n {\n // !@#$ happens, need resize\n let bk = vb.stride;\n\n while (bk < vs)\n {\n bk *= 2;\n }\n this.vbBuffer = new ArrayBuffer(bk);\n this.vbArray = new Float32Array(this.vbBuffer);\n this.vbInts = new Uint32Array(this.vbBuffer);\n vertexBuf.update(this.vbBuffer);\n }\n\n const arr = this.vbArray;\n // const ints = this.vbInts;\n // upload vertices!\n let sz = 0;\n // let tint = 0xffffffff;\n let textureId = 0;\n let shiftU: number = this.offsetX;\n let shiftV: number = this.offsetY;\n\n // let tint = 0xffffffff;\n // const tint = -1;\n\n for (let i = 0; i < points.length; i += POINT_STRUCT_SIZE)\n {\n const eps = 0.5;\n\n if (this.compositeParent)\n {\n const textureIndex = points[i + POINT_STRUCT.TEXTURE_INDEX];\n\n if (boundCountPerBuffer > 1)\n {\n // TODO: what if its more than 4?\n textureId = (textureIndex >> 2);\n shiftU = this.offsetX * (textureIndex & 1);\n shiftV = this.offsetY * ((textureIndex >> 1) & 1);\n }\n else\n {\n textureId = textureIndex;\n shiftU = 0;\n shiftV = 0;\n }\n }\n const x = points[i + POINT_STRUCT.X];\n const y = points[i + POINT_STRUCT.Y];\n const w = points[i + POINT_STRUCT.TILE_WIDTH];\n const h = points[i + POINT_STRUCT.TILE_HEIGHT];\n const u = points[i + POINT_STRUCT.U] + shiftU;\n const v = points[i + POINT_STRUCT.V] + shiftV;\n let rotate = points[i + POINT_STRUCT.ROTATE];\n\n const animX = points[i + POINT_STRUCT.ANIM_X];\n const animY = points[i + POINT_STRUCT.ANIM_Y];\n const animWidth = points[i + POINT_STRUCT.ANIM_COUNT_X] || 1024;\n const animHeight = points[i + POINT_STRUCT.ANIM_COUNT_Y] || 1024;\n\n const animXEncoded = animX + (animWidth * 2048);\n const animYEncoded = animY + (animHeight * 2048);\n const alpha = points[i + POINT_STRUCT.ALPHA];\n let u0: number;\n let v0: number; let u1: number;\n let v1: number; let u2: number;\n let v2: number; let u3: number;\n let v3: number;\n\n if (rotate === 0)\n {\n u0 = u;\n v0 = v;\n u1 = u + w;\n v1 = v;\n u2 = u + w;\n v2 = v + h;\n u3 = u;\n v3 = v + h;\n }\n else\n {\n let w2 = w / 2;\n let h2 = h / 2;\n\n if (rotate % 4 !== 0)\n {\n w2 = h / 2;\n h2 = w / 2;\n }\n const cX = u + w2;\n const cY = v + h2;\n\n rotate = groupD8.add(rotate, groupD8.NW);\n u0 = cX + (w2 * groupD8.uX(rotate));\n v0 = cY + (h2 * groupD8.uY(rotate));\n\n rotate = groupD8.add(rotate, 2); // rotate 90 degrees clockwise\n u1 = cX + (w2 * groupD8.uX(rotate));\n v1 = cY + (h2 * groupD8.uY(rotate));\n\n rotate = groupD8.add(rotate, 2);\n u2 = cX + (w2 * groupD8.uX(rotate));\n v2 = cY + (h2 * groupD8.uY(rotate));\n\n rotate = groupD8.add(rotate, 2);\n u3 = cX + (w2 * groupD8.uX(rotate));\n v3 = cY + (h2 * groupD8.uY(rotate));\n }\n\n arr[sz++] = x;\n arr[sz++] = y;\n arr[sz++] = u0;\n arr[sz++] = v0;\n arr[sz++] = u + eps;\n arr[sz++] = v + eps;\n arr[sz++] = u + w - eps;\n arr[sz++] = v + h - eps;\n arr[sz++] = animXEncoded;\n arr[sz++] = animYEncoded;\n arr[sz++] = textureId;\n arr[sz++] = alpha;\n\n arr[sz++] = x + w;\n arr[sz++] = y;\n arr[sz++] = u1;\n arr[sz++] = v1;\n arr[sz++] = u + eps;\n arr[sz++] = v + eps;\n arr[sz++] = u + w - eps;\n arr[sz++] = v + h - eps;\n arr[sz++] = animXEncoded;\n arr[sz++] = animYEncoded;\n arr[sz++] = textureId;\n arr[sz++] = alpha;\n\n arr[sz++] = x + w;\n arr[sz++] = y + h;\n arr[sz++] = u2;\n arr[sz++] = v2;\n arr[sz++] = u + eps;\n arr[sz++] = v + eps;\n arr[sz++] = u + w - eps;\n arr[sz++] = v + h - eps;\n arr[sz++] = animXEncoded;\n arr[sz++] = animYEncoded;\n arr[sz++] = textureId;\n arr[sz++] = alpha;\n\n arr[sz++] = x;\n arr[sz++] = y + h;\n arr[sz++] = u3;\n arr[sz++] = v3;\n arr[sz++] = u + eps;\n arr[sz++] = v + eps;\n arr[sz++] = u + w - eps;\n arr[sz++] = v + h - eps;\n arr[sz++] = animXEncoded;\n arr[sz++] = animYEncoded;\n arr[sz++] = textureId;\n arr[sz++] = alpha;\n }\n\n vertexBuf.update(arr);\n }\n\n (renderer.geometry as any).bind(vb, shader);\n renderer.geometry.draw(DRAW_MODES.TRIANGLES, rectsCount * 6, 0);\n }\n\n /**\n * @internal\n * @ignore\n */\n isModified(anim: boolean): boolean\n {\n if (this.modificationMarker !== this.pointsBuf.length\n || (anim && this.hasAnimatedTile))\n {\n return true;\n }\n\n return false;\n }\n\n /**\n * This will pull forward the modification marker.\n *\n * @internal\n * @ignore\n */\n clearModify(): void\n {\n this.modificationMarker = this.pointsBuf.length;\n }\n\n /** @override */\n protected _calculateBounds(): void\n {\n const { minX, minY, maxX, maxY } = this.tilemapBounds;\n\n this._bounds.addFrame(this.transform, minX, minY, maxX, maxY);\n }\n\n /** @override */\n public getLocalBounds(rect?: Rectangle): Rectangle\n {\n // we can do a fast local bounds if the sprite has no children!\n if (this.children.length === 0)\n {\n return this.tilemapBounds.getRectangle(rect);\n }\n\n return super.getLocalBounds.call(this, rect);\n }\n\n /** @override */\n destroy(options?: IDestroyOptions): void\n {\n super.destroy(options);\n this.destroyVb();\n }\n\n /**\n * Deprecated signature for {@link Tilemap.tile tile}.\n *\n * @deprecated Since @pixi/tilemap 3.\n */\n addFrame(texture: Texture | string | number, x: number, y: number, animX: number, animY: number): boolean\n {\n this.tile(\n texture,\n x,\n y,\n {\n animX,\n animY,\n }\n );\n\n return true;\n }\n\n /**\n * Deprecated signature for {@link Tilemap.tile tile}.\n *\n * @deprecated Since @pixi/tilemap 3.\n */\n // eslint-disable-next-line max-params\n addRect(\n textureIndex: number,\n u: number,\n v: number,\n x: number,\n y: number,\n tileWidth: number,\n tileHeight: number,\n animX = 0,\n animY = 0,\n rotate = 0,\n animCountX = 1024,\n animCountY = 1024,\n alpha = 1,\n ): this\n {\n return this.tile(\n textureIndex,\n x, y,\n {\n u, v, tileWidth, tileHeight, animX, animY, rotate, animCountX, animCountY, alpha\n }\n );\n }\n}\n","import { Container } from '@pixi/display';\nimport { Texture, Renderer, BaseTexture } from '@pixi/core';\nimport { Matrix } from '@pixi/math';\nimport { Tilemap } from './Tilemap';\nimport { settings } from './settings';\n\nimport type { CanvasRenderer } from '@pixi/canvas-renderer';\nimport type { TileRenderer } from './TileRenderer';\n\n/**\n * A tilemap composite that lazily builds tilesets layered into multiple tilemaps.\n *\n * The composite tileset is the concatenatation of the individual tilesets used in the tilemaps. You can\n * preinitialized it by passing a list of tile textures to the constructor. Otherwise, the composite tilemap\n * is lazily built as you add more tiles with newer tile textures. A new tilemap is created once the last\n * tilemap has reached its limit (as set by {@link CompositeTilemap.texturesPerTilemap texturesPerTilemap}).\n *\n * @example\n * import { Application } from '@pixi/app';\n * import { CompositeTilemap } from '@pixi/tilemap';\n * import { Loader } from '@pixi/loaders';\n *\n * // Setup view & stage.\n * const app = new Application();\n *\n * document.body.appendChild(app.renderer.view);\n * app.stage.interactive = true;\n *\n * // Global reference to the tilemap.\n * let globalTilemap: CompositeTilemap;\n *\n * // Load the tileset spritesheet!\n * Loader.shared.load('atlas.json');\n *\n * // Initialize the tilemap scene when the assets load.\n * Loader.shared.load(function onTilesetLoaded()\n * {\n * const tilemap = new CompositeTilemap();\n *\n * // Setup the game level with grass and dungeons!\n * for (let x = 0; x < 10; x++)\n * {\n * for (let y = 0; y < 10; y++)\n * {\n * tilemap.tile(\n * x % 2 === 0 && (x === y || x + y === 10) ? 'dungeon.png' : 'grass.png',\n * x * 100,\n * y * 100,\n * );\n * }\n * }\n *\n * globalTilemap = app.stage.addChild(tilemap);\n * });\n *\n * // Show a bomb at a random location whenever the user clicks!\n * app.stage.on('click', function onClick()\n * {\n * if (!globalTilemap) return;\n *\n * const x = Math.floor(Math.random() * 10);\n * const y = Math.floor(Math.random() * 10);\n *\n * globalTilemap.tile('bomb.png', x * 100, y * 100);\n * });\n */\nexport class CompositeTilemap extends Container\n{\n /** The hard limit on the number of tile textures used in each tilemap. */\n public readonly texturesPerTilemap: number;\n\n /**\n * The animation frame vector.\n *\n * Animated tiles have four parameters - `animX`, `animY`, `animCountX`, `animCountY`. The textures\n * of adjacent animation frames are at offset `animX` or `animY` of each other, with `animCountX` per\n * row and `animCountY` per column.\n *\n * The animation frame vector specifies which animation frame texture to use. If the x/y coordinate is\n * larger than the `animCountX` or `animCountY` for a specific tile, the modulus is taken.\n */\n public tileAnim: [number, number] = null;\n\n /** The last modified tilemap. */\n protected lastModifiedTilemap: Tilemap = null;\n\n private modificationMarker = 0;\n private shadowColor = new Float32Array([0.0, 0.0, 0.0, 0.5]);\n private _globalMat: Matrix = null;\n\n /**\n * @param tileset - A list of tile base-textures that will be used to eagerly initialized the layered\n * tilemaps. This is only an performance optimization, and using {@link CompositeTilemap.tile tile}\n * will work equivalently.\n */\n constructor(tileset?: Array)\n {\n super();\n\n this.tileset(tileset);\n this.texturesPerTilemap = settings.TEXTURES_PER_TILEMAP;\n }\n\n /**\n * This will preinitialize the tilesets of the layered tilemaps.\n *\n * If used after a tilemap has been created (or a tile added), this will overwrite the tile textures of the\n * existing tilemaps. Passing the tileset to the constructor instead is the best practice.\n *\n * @param tileTextures - The list of tile textures that make up the tileset.\n */\n tileset(tileTextures: Array): this\n {\n if (!tileTextures)\n {\n tileTextures = [];\n }\n\n const texPerChild = this.texturesPerTilemap;\n const len1 = this.children.length;\n const len2 = Math.ceil(tileTextures.length / texPerChild);\n\n for (let i = 0; i < Math.min(len1, len2); i++)\n {\n (this.children[i] as Tilemap).setTileset(\n tileTextures.slice(i * texPerChild, (i + 1) * texPerChild)\n );\n }\n for (let i = len1; i < len2; i++)\n {\n const tilemap = new Tilemap(tileTextures.slice(i * texPerChild, (i + 1) * texPerChild));\n\n tilemap.compositeParent = true;\n tilemap.offsetX = settings.TEXTILE_DIMEN;\n tilemap.offsetY = settings.TEXTILE_DIMEN;\n\n // TODO: Don't use children\n this.addChild(tilemap);\n }\n\n return this;\n }\n\n /** Clears the tilemap composite. */\n clear(): this\n {\n for (let i = 0; i < this.children.length; i++)\n {\n (this.children[i] as Tilemap).clear();\n }\n\n this.modificationMarker = 0;\n\n return this;\n }\n\n /** Changes the rotation of the last added tile. */\n tileRotate(rotate: number): this\n {\n if (this.lastModifiedTilemap)\n {\n this.lastModifiedTilemap.tileRotate(rotate);\n }\n\n return this;\n }\n\n /** Changes `animX`, `animCountX` of the last added tile. */\n tileAnimX(offset: number, count: number): this\n {\n if (this.lastModifiedTilemap)\n {\n this.lastModifiedTilemap.tileAnimX(offset, count);\n }\n\n return this;\n }\n\n /** Changes `animY`, `animCountY` of the last added tile. */\n tileAnimY(offset: number, count: number): this\n {\n if (this.lastModifiedTilemap)\n {\n this.lastModifiedTilemap.tileAnimY(offset, count);\n }\n\n return this;\n }\n\n /**\n * Adds a tile that paints the given tile texture at (x, y).\n *\n * @param tileTexture - The tile texture. You can pass an index into the composite tilemap as well.\n * @param x - The local x-coordinate of the tile's location.\n * @param y - The local y-coordinate of the tile's location.\n * @param options - Additional options to pass to {@link Tilemap.tile}.\n * @param [options.u=texture.frame.x] - The x-coordinate of the texture in its base-texture's space.\n * @param [options.v=texture.frame.y] - The y-coordinate of the texture in its base-texture's space.\n * @param [options.tileWidth=texture.orig.width] - The local width of the tile.\n * @param [options.tileHeight=texture.orig.height] - The local height of the tile.\n * @param [options.animX=0] - For animated tiles, this is the \"offset\" along the x-axis for adjacent\n * animation frame textures in the base-texture.\n * @param [options.animY=0] - For animated tiles, this is the \"offset\" along the y-axis for adjacent\n * animation frames textures in the base-texture.\n * @param [options.rotate=0]\n * @param [options.animCountX=1024] - For animated tiles, this is the number of animation frame textures\n * per row.\n * @param [options.animCountY=1024] - For animated tiles, this is the number of animation frame textures\n * per column.\n * @param [options.alpha=1] - Tile alpha\n * @return This tilemap, good for chaining.\n */\n tile(\n tileTexture: Texture | string | number,\n x: number,\n y: number,\n options: {\n u?: number,\n v?: number,\n tileWidth?: number,\n tileHeight?: number,\n animX?: number,\n animY?: number,\n rotate?: number,\n animCountX?: number,\n animCountY?: number,\n alpha?: number,\n } = {}\n ): this\n {\n let tilemap: Tilemap = null;\n const children = this.children;\n\n this.lastModifiedTilemap = null;\n\n if (typeof tileTexture === 'number')\n {\n const childIndex = tileTexture / this.texturesPerTilemap >> 0;\n let tileIndex = 0;\n\n tilemap = children[childIndex] as Tilemap;\n\n if (!tilemap)\n {\n tilemap = children[0] as Tilemap;\n\n // Silently fail if the tilemap doesn't exist\n if (!tilemap) return this;\n\n tileIndex = 0;\n }\n else\n {\n tileIndex = tileTexture % this.texturesPerTilemap;\n }\n\n tilemap.tile(\n tileIndex,\n x,\n y,\n options,\n );\n }\n else\n {\n if (typeof tileTexture === 'string')\n {\n tileTexture = Texture.from(tileTexture);\n }\n\n // Probe all tilemaps to find which tileset contains the base-texture.\n for (let i = 0; i < children.length; i++)\n {\n const child = children[i] as Tilemap;\n const tex = child.getTileset();\n\n for (let j = 0; j < tex.length; j++)\n {\n if (tex[j] === tileTexture.baseTexture)\n {\n tilemap = child;\n break;\n }\n }\n\n if (tilemap)\n {\n break;\n }\n }\n\n // If no tileset contains the base-texture, attempt to add it.\n if (!tilemap)\n {\n // Probe the tilemaps to find one below capacity. If so, add the texture into that tilemap.\n for (let i = children.length - 1; i >= 0; i--)\n {\n const child = children[i] as Tilemap;\n\n if (child.getTileset().length < this.texturesPerTilemap)\n {\n tilemap = child;\n child.getTileset().push(tileTexture.baseTexture);\n break;\n }\n }\n\n // Otherwise, create a new tilemap initialized with that tile texture.\n if (!tilemap)\n {\n tilemap = new Tilemap(tileTexture.baseTexture);\n tilemap.compositeParent = true;\n tilemap.offsetX = settings.TEXTILE_DIMEN;\n tilemap.offsetY = settings.TEXTILE_DIMEN;\n\n this.addChild(tilemap);\n }\n }\n\n tilemap.tile(\n tileTexture,\n x,\n y,\n options,\n );\n }\n\n this.lastModifiedTilemap = tilemap;\n\n return this;\n }\n\n renderCanvas(renderer: CanvasRenderer): void\n {\n if (!this.visible || this.worldAlpha <= 0 || !this.renderable)\n {\n return;\n }\n\n const tilemapPlugin = renderer.plugins.tilemap;\n\n if (tilemapPlugin && !tilemapPlugin.dontUseTransform)\n {\n const wt = this.worldTransform;\n\n renderer.context.setTransform(\n wt.a,\n wt.b,\n wt.c,\n wt.d,\n wt.tx * renderer.resolution,\n wt.ty * renderer.resolution\n );\n }\n\n const layers = this.children;\n\n for (let i = 0; i < layers.length; i++)\n {\n const layer = (layers[i] as Tilemap);\n\n layer.tileAnim = this.tileAnim;\n layer.renderCanvasCore(renderer);\n }\n }\n\n render(renderer: Renderer): void\n {\n if (!this.visible || this.worldAlpha <= 0 || !this.renderable)\n {\n return;\n }\n\n const plugin = renderer.plugins.tilemap as TileRenderer;\n const shader = plugin.getShader();\n\n renderer.batch.setObjectRenderer(plugin);\n\n // TODO: dont create new array, please\n this._globalMat = shader.uniforms.projTransMatrix;\n renderer.globalUniforms.uniforms.projectionMatrix.copyTo(this._globalMat).append(this.worldTransform);\n shader.uniforms.shadowColor = this.shadowColor;\n shader.uniforms.animationFrame = this.tileAnim || plugin.tileAnim;\n\n renderer.shader.bind(shader, false);\n\n const layers = this.children;\n\n for (let i = 0; i < layers.length; i++)\n {\n (layers[i] as Tilemap).renderWebGLCore(renderer, plugin);\n }\n }\n\n /**\n * @internal\n * @ignore\n */\n isModified(anim: boolean): boolean\n {\n const layers = this.children;\n\n if (this.modificationMarker !== layers.length)\n {\n return true;\n }\n for (let i = 0; i < layers.length; i++)\n {\n if ((layers[i] as Tilemap).isModified(anim))\n {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * @internal\n * @ignore\n */\n clearModify(): void\n {\n const layers = this.children;\n\n this.modificationMarker = layers.length;\n for (let i = 0; i < layers.length; i++)\n {\n (layers[i] as Tilemap).clearModify();\n }\n }\n\n /**\n * @deprecated Since @pixi/tilemap 3.\n * @see CompositeTilemap.tile\n */\n addFrame(\n texture: Texture | string | number,\n x: number,\n y: number,\n animX?: number,\n animY?: number,\n animWidth?: number,\n animHeight?: number,\n alpha?: number\n ): this\n {\n return this.tile(\n texture,\n x, y,\n {\n animX,\n animY,\n animCountX: animWidth,\n animCountY: animHeight,\n alpha\n }\n );\n }\n\n /**\n * @deprecated @pixi/tilemap 3\n * @see CompositeTilemap.tile\n */\n // eslint-disable-next-line max-params\n addRect(\n textureIndex: number,\n u: number,\n v: number,\n x: number,\n y: number,\n tileWidth: number,\n tileHeight: number,\n animX?: number,\n animY?: number,\n rotate?: number,\n animWidth?: number,\n animHeight?: number\n ): this\n {\n const childIndex: number = textureIndex / this.texturesPerTilemap >> 0;\n const textureId: number = textureIndex % this.texturesPerTilemap;\n\n if (this.children[childIndex] && (this.children[childIndex] as Tilemap).getTileset())\n {\n this.lastModifiedTilemap = (this.children[childIndex] as Tilemap);\n this.lastModifiedTilemap.addRect(\n textureId, u, v, x, y, tileWidth, tileHeight, animX, animY, rotate, animWidth, animHeight\n );\n }\n else\n {\n this.lastModifiedTilemap = null;\n }\n\n return this;\n }\n\n /**\n * Alias for {@link CompositeTilemap.tileset tileset}.\n *\n * @deprecated Since @pixi/tilemap 3.\n */\n setBitmaps = this.tileset;\n\n /**\n * @deprecated Since @pixi/tilemap 3.\n * @readonly\n * @see CompositeTilemap.texturesPerTilemap\n */\n get texPerChild(): number { return this.texturesPerTilemap; }\n}\n","import { ALPHA_MODES } from '@pixi/constants';\nimport { BaseTexture, Renderer, Resource, Texture, GLTexture } from '@pixi/core';\nimport { settings } from './settings';\n\nexport interface TextileOptions\n{\n\tTEXTILE_DIMEN: number;\n\tTEXTILE_UNITS: number;\n\tDO_CLEAR?: boolean;\n}\n\ntype TextureTile = {\n\tdirtyId: number;\n\tx: number;\n\ty: number;\n\tbaseTexture: BaseTexture;\n};\n\n// For some reason ESLint goes mad with indendation in this file ^&^\n/* eslint-disable indent */\n\n/**\n * This texture tiling resource can be used to upload multiple base-textures together.\n *\n * This resource combines multiple base-textures into a \"textile\". They're laid out in\n * a dual column format, placed in row-order order. The size of each tile is predefined,\n * and defaults to {@link settings.TEXTILE_DIMEN}. This means that each input base-texture\n * must is smaller than that along both its width and height.\n *\n * @see settings.TEXTILE_UNITS\n */\nexport class TextileResource extends Resource\n{\n\t/** The base-texture that contains all the texture tiles. */\n\tpublic baseTexture: BaseTexture = null;\n\n\tprivate readonly doClear: boolean;\n\tprivate readonly tileDimen: number;\n\tprivate readonly tiles: Array;\n\n\tprivate _clearBuffer: Uint8Array = null;\n\n\t/**\n\t * @param options - This will default to the \"settings\" exported by @pixi/tilemap.\n\t * @param options.TEXTILE_DIMEN - The dimensions of each tile.\n\t * @param options.TEXTILE_UNITS - The number of texture tiles.\n\t */\n\tconstructor(options: TextileOptions = settings)\n\t{\n\t\tsuper(\n\t\t\toptions.TEXTILE_DIMEN * 2,\n\t\t\toptions.TEXTILE_DIMEN * Math.ceil(options.TEXTILE_UNITS / 2),\n\t\t);\n\n\t\tconst tiles: TextureTile[] = this.tiles = new Array(options.TEXTILE_UNITS);\n\n\t\tthis.doClear = !!options.DO_CLEAR;\n\t\tthis.tileDimen = options.TEXTILE_DIMEN;\n\n\t\tfor (let j = 0; j < options.TEXTILE_UNITS; j++)\n\t\t{\n\t\t\ttiles[j] = {\n\t\t\t\tdirtyId: 0,\n\t\t\t\tx: options.TEXTILE_DIMEN * (j & 1),\n\t\t\t\ty: options.TEXTILE_DIMEN * (j >> 1),\n\t\t\t\tbaseTexture: Texture.WHITE.baseTexture,\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Sets the texture to be uploaded for the given tile.\n\t *\n\t * @param index - The index of the tile being set.\n\t * @param texture - The texture with the base-texture to upload.\n\t */\n\ttile(index: number, texture: BaseTexture): void\n\t{\n\t\tconst tile = this.tiles[index];\n\n\t\tif (tile.baseTexture === texture)\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\ttile.baseTexture = texture;\n\t\tthis.baseTexture.update();\n\n\t\tthis.tiles[index].dirtyId = (this.baseTexture as any).dirtyId;\n\t}\n\n\t/** @override */\n\tbind(baseTexture: BaseTexture): void\n\t{\n\t\tif (this.baseTexture)\n\t\t{\n\t\t\tthrow new Error('Only one baseTexture is allowed for this resource!');\n\t\t}\n\n\t\tthis.baseTexture = baseTexture;\n\t\tsuper.bind(baseTexture);\n\t}\n\n\t/** @override */\n\tupload(renderer: Renderer, texture: BaseTexture, glTexture: GLTexture): boolean\n\t{\n\t\tconst { gl } = renderer;\n\t\tconst { width, height } = this;\n\n\t\tgl.pixelStorei(\n\t\t\tgl.UNPACK_PREMULTIPLY_ALPHA_WEBGL,\n\t\t\ttexture.alphaMode === undefined || texture.alphaMode === ALPHA_MODES.UNPACK\n\t\t);\n\n\t\tif (glTexture.dirtyId < 0)\n\t\t{\n\t\t\t(glTexture as any).width = width;\n\t\t\t(glTexture as any).height = height;\n\n\t\t\tgl.texImage2D(texture.target, 0,\n\t\t\t\ttexture.format,\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\t0,\n\t\t\t\ttexture.format,\n\t\t\t\ttexture.type,\n\t\t\t\tnull);\n\t\t}\n\n\t\tconst doClear = this.doClear;\n\t\tconst tiles = this.tiles;\n\n\t\tif (doClear && !this._clearBuffer)\n\t\t{\n\t\t\tthis._clearBuffer = new Uint8Array(settings.TEXTILE_DIMEN * settings.TEXTILE_DIMEN * 4);\n\t\t}\n\n\t\tfor (let i = 0; i < tiles.length; i++)\n\t\t{\n\t\t\tconst spr = tiles[i];\n\t\t\tconst tex = spr.baseTexture;\n\n\t\t\tif (glTexture.dirtyId >= this.tiles[i].dirtyId)\n\t\t\t{\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst res = tex.resource as any;\n\n\t\t\tif (!tex.valid || !res || !res.source)\n\t\t\t{\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (doClear && (tex.width < this.tileDimen || tex.height < this.tileDimen))\n\t\t\t{\n\t\t\t\tgl.texSubImage2D(texture.target, 0,\n\t\t\t\t\tspr.x,\n\t\t\t\t\tspr.y,\n\t\t\t\t\tthis.tileDimen,\n\t\t\t\t\tthis.tileDimen,\n\t\t\t\t\ttexture.format,\n\t\t\t\t\ttexture.type,\n\t\t\t\t\tthis._clearBuffer);\n\t\t\t}\n\n\t\t\tgl.texSubImage2D(texture.target, 0,\n\t\t\t\tspr.x,\n\t\t\t\tspr.y,\n\t\t\t\ttexture.format,\n\t\t\t\ttexture.type,\n\t\t\t\tres.source);\n\t\t}\n\n\t\treturn true;\n\t}\n}\n","import type { TilemapShader } from './TilemapShader';\n\n/**\n * This will generate fragment shader code that samples the correct texture into the \"color\" variable.\n *\n * @internal\n * @ignore\n * @param maxTextures - The texture array length in the shader's uniforms.\n */\nfunction generateSampleSrc(maxTextures: number): string\n{\n let src = '';\n\n src += '\\n';\n src += '\\n';\n\n src += 'if(vTextureId <= -1.0) {';\n src += '\\n\\tcolor = shadowColor;';\n src += '\\n}';\n\n for (let i = 0; i < maxTextures; i++)\n {\n src += '\\nelse ';\n\n if (i < maxTextures - 1)\n {\n src += `if(textureId == ${i}.0)`;\n }\n\n src += '\\n{';\n src += `\\n\\tcolor = texture2D(uSamplers[${i}], textureCoord * uSamplerSize[${i}]);`;\n src += '\\n}';\n }\n\n src += '\\n';\n src += '\\n';\n\n return src;\n}\n\n/**\n * @internal\n * @ignore\n * @param shader\n * @param maxTextures\n */\nexport function fillSamplers(shader: TilemapShader, maxTextures: number): void\n{\n const sampleValues: Array = [];\n\n for (let i = 0; i < maxTextures; i++)\n {\n sampleValues[i] = i;\n }\n\n shader.uniforms.uSamplers = sampleValues;\n\n const samplerSize: Array = [];\n\n for (let i = 0; i < maxTextures; i++)\n {\n // These are overwritten by TileRenderer when textures actually bound.\n samplerSize.push(1.0 / 2048);\n samplerSize.push(1.0 / 2048);\n }\n\n shader.uniforms.uSamplerSize = samplerSize;\n}\n\n/**\n * @internal\n * @ignore\n * @param maxTextures\n * @param fragmentSrc\n * @returns\n */\nexport function generateFragmentSrc(maxTextures: number, fragmentSrc: string): string\n{\n return fragmentSrc.replace(/%count%/gi, `${maxTextures}`)\n .replace(/%forloop%/gi, generateSampleSrc(maxTextures));\n}\n","// eslint-disable-next-line @typescript-eslint/triple-slash-reference, spaced-comment\n///\n\nimport * as shaderGenerator from './shaderGenerator';\nimport tilemapVertexTemplateSrc from './tilemap.vert';\nimport tilemapFragmentTemplateSrc from './tilemap.frag';\n\nimport { Buffer, Geometry, Shader, Program } from '@pixi/core';\nimport { Matrix } from '@pixi/math';\n\n// For some reason ESLint goes mad with indendation in this file ^&^\n/* eslint-disable no-mixed-spaces-and-tabs, indent */\n\nexport class TilemapShader extends Shader\n{\n\tmaxTextures = 0;\n\n\tconstructor(maxTextures: number)\n\t{\n\t super(\n\t new Program(\n\t\t\t\ttilemapVertexTemplateSrc,\n\t\t\t\tshaderGenerator.generateFragmentSrc(maxTextures, tilemapFragmentTemplateSrc)\n\t\t\t),\n\t {\n\t animationFrame: new Float32Array(2),\n\t uSamplers: [],\n\t uSamplerSize: [],\n\t projTransMatrix: new Matrix()\n\t }\n\t );\n\n\t this.maxTextures = maxTextures;\n\t shaderGenerator.fillSamplers(this, this.maxTextures);\n\t}\n}\n\nexport class TilemapGeometry extends Geometry\n{\n\tvertSize = 12;\n\tvertPerQuad = 4;\n\tstride = this.vertSize * 4;\n\tlastTimeAccess = 0;\n\n\tconstructor()\n\t{\n\t super();\n\n\t const buf = this.buf = new Buffer(new Float32Array(2), true, false);\n\n\t this.addAttribute('aVertexPosition', buf, 0, false, 0, this.stride, 0)\n\t .addAttribute('aTextureCoord', buf, 0, false, 0, this.stride, 2 * 4)\n\t .addAttribute('aFrame', buf, 0, false, 0, this.stride, 4 * 4)\n\t .addAttribute('aAnim', buf, 0, false, 0, this.stride, 8 * 4)\n\t .addAttribute('aTextureId', buf, 0, false, 0, this.stride, 10 * 4)\n .addAttribute('aAlpha', buf, 0, false, 0, this.stride, 11 * 4);\n\t}\n\n\tbuf: Buffer;\n}\n","import { WRAP_MODES } from '@pixi/constants';\nimport { BaseTexture, Buffer, ObjectRenderer, Renderer } from '@pixi/core';\nimport { settings } from './settings';\nimport { TilemapGeometry, TilemapShader } from './TilemapShader';\nimport { TextileResource } from './TextileResource';\nimport * as utils from '@pixi/utils';\n\n// For some reason ESLint goes mad with indendation in this file ^&^\n/* eslint-disable no-mixed-spaces-and-tabs, indent */\n\n/**\n * Rendering helper pipeline for tilemaps. This plugin is registered automatically.\n */\nexport class TileRenderer extends ObjectRenderer\n{\n\t/** The managing renderer */\n\tpublic readonly renderer: Renderer;\n\n\t/** The tile animation frame */\n\tpublic tileAnim = [0, 0];\n\n\tprivate ibLen = 0;// index buffer length\n\n\t/** The index buffer for the tilemaps to share. */\n\tprivate indexBuffer: Buffer = null;\n\n\t/** The shader used to render tilemaps. */\n\tprivate shader: TilemapShader;\n\n\t/**\n\t * {@link TextileResource} instances used to upload textures batched in tiled groups. This is\n\t * used only if {@link settings.TEXTURES_PER_TILEMAP} is greater than 1.\n\t */\n\tprivate textiles: Array = [];\n\n\t/** @param renderer - The managing renderer */\n\tconstructor(renderer: Renderer)\n\t{\n\t super(renderer);\n\n\t this.shader = new TilemapShader(settings.TEXTURES_PER_TILEMAP);\n\t this.indexBuffer = new Buffer(undefined, true, true);\n\t this.checkIndexBuffer(2000);\n\t this.makeTextiles();\n\t}\n\n\t/**\n\t * Binds the tile textures to the renderer, and updates the tilemap shader's `uSamplerSize` uniform.\n\t *\n\t * If {@link settings.TEXTILE_UNITS}\n\t *\n\t * @param renderer - The renderer to which the textures are to be bound.\n\t * @param textures - The tile textures being bound.\n\t */\n\tbindTileTextures(renderer: Renderer, textures: Array): void\n\t{\n\t const len = textures.length;\n\t\tconst shader = this.shader;\n\t const maxTextures = settings.TEXTURES_PER_TILEMAP;\n\t\tconst samplerSize: Array = shader.uniforms.uSamplerSize;\n\n\t if (len > settings.TEXTILE_UNITS * maxTextures)\n\t {\n\t\t\t// TODO: Show error message instead of silently failing!\n\t return;\n\t }\n\n\t\tif (settings.TEXTILE_UNITS <= 1)\n\t {\n\t\t\t// Bind each texture directly & update samplerSize.\n\t\t\tfor (let i = 0; i < textures.length; i++)\n\t\t\t{\n\t\t\t\tconst texture = textures[i];\n\n\t\t\t\tif (!texture || !texture.valid)\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\trenderer.texture.bind(textures[i], i);\n\n\t\t\t\tsamplerSize[i * 2] = 1.0 / textures[i].realWidth;\n\t\t\t\tsamplerSize[(i * 2) + 1] = 1.0 / textures[i].realHeight;\n\t\t\t}\n\t }\n\t\telse\n\t\t{\n\t\t\t// Ensure we have enough textiles, in case settings.TEXTILE_UNITS was modified.\n\t\t\tthis.makeTextiles();\n\n\t\t\tconst usedTextiles = Math.ceil(len / settings.TEXTILE_UNITS);\n\n\t\t\t// First ensure each textile has all tiles point to the right textures.\n\t\t\tfor (let i = 0; i < len; i++)\n\t\t\t{\n\t\t\t\tconst texture = textures[i];\n\n\t\t\t\tif (texture && texture.valid)\n\t\t\t\t{\n\t\t\t\t\tconst resourceIndex = Math.floor(i / settings.TEXTILE_UNITS);\n\t\t\t\t\tconst tileIndex = i % settings.TEXTILE_UNITS;\n\n\t\t\t\t\tthis.textiles[resourceIndex].tile(tileIndex, texture);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Then bind the textiles + update samplerSize.\n\t\t\tfor (let i = 0; i < usedTextiles; i++)\n\t\t\t{\n\t\t\t\trenderer.texture.bind(this.textiles[i].baseTexture, i);\n\n\t\t\t\tsamplerSize[i * 2] = 1.0 / this.textiles[i].width;\n\t\t\t\tsamplerSize[(i * 2) + 1] = 1.0 / this.textiles[i].baseTexture.height;\n\t\t\t}\n\t\t}\n\n\t\tshader.uniforms.uSamplerSize = samplerSize;\n\t}\n\n\tstart(): void\n\t{\n\t // sorry, nothing\n\t}\n\n\t/**\n\t * @internal\n\t * @ignore\n\t */\n\tcreateVb(): TilemapGeometry\n\t{\n\t const geom = new TilemapGeometry();\n\n\t geom.addIndex(this.indexBuffer);\n\t geom.lastTimeAccess = Date.now();\n\n\t return geom;\n\t}\n\n\t/** @return The {@link TilemapShader} shader that this rendering pipeline is using. */\n\tgetShader(): TilemapShader { return this.shader; }\n\n\tdestroy(): void\n\t{\n\t super.destroy();\n\t // this.rectShader.destroy();\n\t this.shader = null;\n\t}\n\n\tpublic checkIndexBuffer(size: number, _vb: TilemapGeometry = null): void\n\t{\n\t const totalIndices = size * 6;\n\n\t if (totalIndices <= this.ibLen)\n\t {\n\t return;\n\t }\n\n\t let len = totalIndices;\n\n\t while (len < totalIndices)\n\t {\n\t len <<= 1;\n\t }\n\n\t this.ibLen = totalIndices;\n\t this.indexBuffer.update(utils.createIndicesForQuads(size,\n\t settings.use32bitIndex ? new Uint32Array(size * 6) : undefined));\n\n\t // \tTODO: create new index buffer instead?\n\t // if (vb) {\n\t // \tconst curIndex = vb.getIndex();\n\t // \tif (curIndex !== this.indexBuffer && (curIndex.data as any).length < totalIndices) {\n\t // \t\tthis.swapIndex(vb, this.indexBuffer);\n\t // \t}\n\t // }\n\t}\n\n\t/** Makes textile resources and initializes {@link TileRenderer.textiles}. */\n\tprivate makeTextiles(): void\n\t{\n\t if (settings.TEXTILE_UNITS <= 1)\n\t {\n\t return;\n\t }\n\n\t for (let i = 0; i < settings.TEXTILE_UNITS; i++)\n\t {\n\t\t\tif (this.textiles[i]) continue;\n\n\t\t\tconst resource = new TextileResource();\n\t const baseTex = new BaseTexture(resource);\n\n\t baseTex.scaleMode = settings.TEXTILE_SCALE_MODE;\n\t baseTex.wrapMode = WRAP_MODES.CLAMP;\n\n\t\t\tthis.textiles[i] = resource;\n\t }\n\t}\n}\n\nRenderer.registerPlugin('tilemap', TileRenderer as any);\n","import { CanvasTileRenderer } from './CanvasTileRenderer';\nimport { CompositeTilemap } from './CompositeTilemap';\nimport { Constant } from './settings';\nimport { TextileResource } from './TextileResource';\nimport { Tilemap } from './Tilemap';\nimport { TilemapShader, TilemapGeometry } from './TilemapShader';\nimport { TileRenderer } from './TileRenderer';\n\n// Prevent SCALE_MODES from becoming lazy import in Constant.ts - which causes a import() in the declaration file,\n// which causes API extractor to fail https://github.com/microsoft/rushstack/issues/2140\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport * as constants from '@pixi/constants';\n\n// eslint-disable-next-line camelcase\nexport const pixi_tilemap = {\n CanvasTileRenderer,\n CompositeRectTileLayer: CompositeTilemap,\n CompositeTilemap,\n Constant,\n TextileResource,\n MultiTextureResource: TextileResource,\n RectTileLayer: Tilemap,\n Tilemap,\n TilemapShader,\n TilemapGeometry,\n RectTileShader: TilemapShader,\n RectTileGeom: TilemapGeometry,\n TileRenderer,\n};\n\nexport * from './CanvasTileRenderer';\nexport * from './CompositeTilemap';\nexport * from './settings';\nexport * from './TextileResource';\nexport * from './Tilemap';\nexport * from './TilemapShader';\nexport * from './shaderGenerator';\nexport * from './TileRenderer';\n\nexport { CompositeTilemap as CompositeRectTileLayer } from './CompositeTilemap';\nexport { Tilemap as RectTileLayer } from './Tilemap';\n"],"names":["Renderer"],"mappings":";;;;;;;;;;;;;;;;;;;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAEA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IC9BA;IACA;IACA;IACA;IACA;IACA;;IAEA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;;;uGC7CA;AACA;AACA;AACA;AACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;;AAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAEA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;ICltBA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAEA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IC7eA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAEA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;;IC7KA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAEA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAEA;IACA;IACA;IACA;;;;;;IChFA;AASA;IACA;IACA;AACA;;IAEA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;;IAEA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;;ICpDA;IACA;AACA;IACA;IACA;IACA;;IAEA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;AACAA;;IC3LA;;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file +{"version":3,"file":"pixi-tilemap.umd.js","sources":["../src/CanvasTileRenderer.ts","../src/settings.ts","../src/Tilemap.ts","../src/CompositeTilemap.ts","../src/TextileResource.ts","../src/shaderGenerator.ts","../src/TilemapShader.ts","../src/TileRenderer.ts","../src/index.ts"],"sourcesContent":["import type { AbstractRenderer } from '@pixi/core';\n\n/**\n * The renderer plugin for canvas. It isn't registered by default.\n *\n * ```\n * import { CanvasTileRenderer } from '@pixi/tilemap';\n * import { CanvasRenderer } from '@pixi/canvas-core';\n *\n * // You must register this yourself (optional). @pixi/tilemap doesn't do it to\n * // prevent a hard dependency on @pixi/canvas-core.\n * CanvasRenderer.registerPlugin('tilemap', CanvasTileRenderer);\n * ```\n */\n// TODO: Move to @pixi/tilemap-canvas\nexport class CanvasTileRenderer\n{\n /** The renderer */\n renderer: AbstractRenderer;\n\n /** The global tile animation state */\n tileAnim = [0, 0];\n\n /** @deprecated */\n dontUseTransform = false;\n\n /** @param renderer */\n constructor(renderer: AbstractRenderer)\n {\n this.renderer = renderer;\n this.tileAnim = [0, 0];\n }\n}\n","import { SCALE_MODES } from '@pixi/constants';\n\n/**\n * These are additional @pixi/tilemap options.\n *\n * This settings should not be changed after the renderer has initialized; otherwise, the behavior\n * is undefined.\n */\nexport const settings = {\n /** The default number of textures per tilemap in a tilemap composite. */\n TEXTURES_PER_TILEMAP: 16,\n\n /**\n * The width/height of each texture tile in a {@link TEXTILE_DIMEN}. This is 1024px by default.\n *\n * This should fit all tile base-textures; otherwise, {@link TextileResource} may fail to correctly\n * upload the textures togther in a tiled fashion.\n */\n TEXTILE_DIMEN: 1024,\n\n /**\n * The number of texture tiles per {@link TextileResource}.\n *\n * Texture tiling is disabled by default, and so this is set to `1` by default. If it is set to a\n * higher value, textures will be uploaded together in a tiled fashion.\n *\n * Since {@link TextileResource} is a dual-column format, this should be even for packing\n * efficiency. The optimal value is usually 4.\n */\n TEXTILE_UNITS: 1,\n\n /** The scaling mode of the combined texture tiling. */\n TEXTILE_SCALE_MODE: SCALE_MODES.LINEAR,\n\n /** This will enable 32-bit index buffers. It's useful when you have more than 16K tiles. */\n use32bitIndex: false,\n\n /** Flags whether textiles should be cleared when each tile is uploaded. */\n DO_CLEAR: true,\n\n // Backward compatibility\n get maxTextures(): number { return this.MAX_TEXTURES; },\n set maxTextures(value: number) { this.MAX_TEXTURES = value; },\n\n get boundSize(): number { return this.TEXTURE_TILE_DIMEN; },\n set boundSize(value: number) { this.TILE_TEXTURE_DIMEN = value; },\n\n get boundCountPerBuffer(): number { return this.TEXTILE_UNITS; },\n set boundCountPerBuffer(value: number) { this.TEXTILE_UNITS = value; },\n};\n\n// @deprecated\nexport const Constant = settings;\n","import { Container, Bounds } from '@pixi/display';\nimport { DRAW_MODES } from '@pixi/constants';\nimport { Texture, Renderer } from '@pixi/core';\nimport { TileRenderer } from './TileRenderer';\nimport { Matrix, Rectangle, groupD8 } from '@pixi/math';\nimport { settings } from './settings';\n\nimport type { BaseTexture } from '@pixi/core';\nimport type { CanvasRenderer } from '@pixi/canvas-renderer';\nimport type { IDestroyOptions } from '@pixi/display';\nimport type { TilemapGeometry } from './TilemapShader';\n\nenum POINT_STRUCT {\n U = 0,\n V,\n X,\n Y,\n TILE_WIDTH,\n TILE_HEIGHT,\n ROTATE,\n ANIM_X,\n ANIM_Y,\n TEXTURE_INDEX,\n ANIM_COUNT_X,\n ANIM_COUNT_Y,\n ALPHA,\n}\n\nexport const POINT_STRUCT_SIZE = (Object.keys(POINT_STRUCT).length / 2);\n\n/**\n * A rectangular tilemap implementation that renders a predefined set of tile textures.\n *\n * The {@link Tilemap.tileset tileset} of a tilemap defines the list of base-textures that can be painted in the\n * tilemap. A texture is identified using its base-texture's index into the this list, i.e. changing the base-texture\n * at a given index in the tileset modifies the paint of all tiles pointing to that index.\n *\n * The size of the tileset is limited by the texture units supported by the client device. The minimum supported\n * value is 8, as defined by the WebGL 1 specification. `gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS`) can be used\n * to extract this limit. {@link CompositeTilemap} can be used to get around this limit by layering multiple tilemap\n * instances.\n *\n * @example\n * import { Tilemap } from '@pixi/tilemap';\n * import { Loader } from '@pixi/loaders';\n *\n * // Add the spritesheet into your loader!\n * Loader.shared.add('atlas', 'assets/atlas.json');\n *\n * // Make the tilemap once the tileset assets are available.\n * Loader.shared.load(function onTilesetLoaded()\n * {\n * // The base-texture is shared between all the tile textures.\n * const tilemap = new Tilemap([Texture.from('grass.png').baseTexture])\n * .tile('grass.png', 0, 0)\n * .tile('grass.png', 100, 100)\n * .tile('brick_wall.png', 0, 100);\n * });\n */\nexport class Tilemap extends Container\n{\n shadowColor = new Float32Array([0.0, 0.0, 0.0, 0.5]);\n _globalMat: Matrix = null;\n\n /**\n * The tile animation frame.\n *\n * @see CompositeTilemap.tileAnim\n */\n public tileAnim: [number, number] = null;\n\n /**\n * This is the last uploaded size of the tilemap geometry.\n * @ignore\n */\n modificationMarker = 0;\n\n /** @ignore */\n offsetX = 0;\n\n /** @ignore */\n offsetY = 0;\n\n /** @ignore */\n compositeParent = false;\n\n /**\n * The list of base-textures being used in the tilemap.\n *\n * This should not be shuffled after tiles have been added into this tilemap. Usually, only tile textures\n * should be added after tiles have been added into the map.\n */\n protected tileset: Array;\n\n /**\n * The local bounds of the tilemap itself. This does not include DisplayObject children.\n */\n protected readonly tilemapBounds = new Bounds();\n\n /** Flags whether any animated tile was added. */\n protected hasAnimatedTile = false;\n\n /** The interleaved geometry of the tilemap. */\n private pointsBuf: Array = [];\n\n /**\n * @param tileset - The tileset to use for the tilemap. This can be reset later with {@link Tilemap.setTileset}. The\n * base-textures in this array must not be duplicated.\n */\n constructor(tileset: BaseTexture | Array)\n {\n super();\n this.setTileset(tileset);\n }\n\n /**\n * @returns The tileset of this tilemap.\n */\n getTileset(): Array\n {\n return this.tileset;\n }\n\n /**\n * Define the tileset used by the tilemap.\n *\n * @param tileset - The list of textures to use in the tilemap. If a base-texture (not array) is passed, it will\n * be wrapped into an array. This should not contain any duplicates.\n */\n setTileset(tileset: BaseTexture | Array = []): this\n {\n if (!Array.isArray(tileset))\n {\n tileset = [tileset];\n }\n for (let i = 0; i < tileset.length; i++)\n {\n if ((tileset[i] as unknown as Texture).baseTexture)\n {\n tileset[i] = (tileset[i] as unknown as Texture).baseTexture;\n }\n }\n\n this.tileset = tileset;\n\n return this;\n }\n\n /** Clears all the tiles added into this tilemap. */\n clear(): this\n {\n this.pointsBuf.length = 0;\n this.modificationMarker = 0;\n this.tilemapBounds.clear();\n this.hasAnimatedTile = false;\n\n return this;\n }\n\n /**\n * Adds a tile that paints the given texture at (x, y).\n *\n * @param tileTexture - The tiling texture to render.\n * @param x - The local x-coordinate of the tile's position.\n * @param y - The local y-coordinate of the tile's position.\n * @param options - Additional tile options.\n * @param [options.u=texture.frame.x] - The x-coordinate of the texture in its base-texture's space.\n * @param [options.v=texture.frame.y] - The y-coordinate of the texture in its base-texture's space.\n * @param [options.tileWidth=texture.orig.width] - The local width of the tile.\n * @param [options.tileHeight=texture.orig.height] - The local height of the tile.\n * @param [options.animX=0] - For animated tiles, this is the \"offset\" along the x-axis for adjacent\n * animation frame textures in the base-texture.\n * @param [options.animY=0] - For animated tiles, this is the \"offset\" along the y-axis for adjacent\n * animation frames textures in the base-texture.\n * @param [options.rotate=0]\n * @param [options.animCountX=1024] - For animated tiles, this is the number of animation frame textures\n * per row.\n * @param [options.animCountY=1024] - For animated tiles, this is the number of animation frame textures\n * per column.\n * @param [options.alpha=1] - Tile alpha\n * @return This tilemap, good for chaining.\n */\n tile(\n tileTexture: number | string | Texture | BaseTexture,\n x: number,\n y: number,\n options: {\n u?: number,\n v?: number,\n tileWidth?: number,\n tileHeight?: number,\n animX?: number,\n animY?: number,\n rotate?: number,\n animCountX?: number,\n animCountY?: number,\n alpha?: number,\n } = {}\n ): this\n {\n let baseTexture: BaseTexture;\n let textureIndex = -1;\n\n if (typeof tileTexture === 'number')\n {\n textureIndex = tileTexture;\n baseTexture = this.tileset[textureIndex];\n }\n else\n {\n let texture: Texture | BaseTexture;\n\n if (typeof tileTexture === 'string')\n {\n texture = Texture.from(tileTexture);\n }\n else\n {\n texture = tileTexture;\n }\n\n const textureList = this.tileset;\n\n for (let i = 0; i < textureList.length; i++)\n {\n if (textureList[i] === texture.castToBaseTexture())\n {\n textureIndex = i;\n break;\n }\n }\n\n if ('baseTexture' in texture)\n {\n options.u = options.u ?? texture.frame.x;\n options.v = options.v ?? texture.frame.y;\n options.tileWidth = options.tileWidth ?? texture.orig.width;\n options.tileHeight = options.tileHeight ?? texture.orig.height;\n }\n\n baseTexture = texture.castToBaseTexture();\n }\n\n if (!baseTexture || textureIndex < 0)\n {\n console.error('The tile texture was not found in the tilemap tileset.');\n\n return this;\n }\n\n const {\n u = 0,\n v = 0,\n tileWidth = baseTexture.realWidth,\n tileHeight = baseTexture.realHeight,\n animX = 0,\n animY = 0,\n rotate = 0,\n animCountX = 1024,\n animCountY = 1024,\n alpha = 1,\n } = options;\n\n const pb = this.pointsBuf;\n\n this.hasAnimatedTile = this.hasAnimatedTile || animX > 0 || animY > 0;\n\n pb.push(u);\n pb.push(v);\n pb.push(x);\n pb.push(y);\n pb.push(tileWidth);\n pb.push(tileHeight);\n pb.push(rotate);\n pb.push(animX | 0);\n pb.push(animY | 0);\n pb.push(textureIndex);\n pb.push(animCountX);\n pb.push(animCountY);\n pb.push(alpha);\n\n this.tilemapBounds.addFramePad(x, y, x + tileWidth, y + tileHeight, 0, 0);\n\n return this;\n }\n\n /** Changes the rotation of the last tile. */\n tileRotate(rotate: number): void\n {\n const pb = this.pointsBuf;\n\n pb[pb.length - (POINT_STRUCT_SIZE - POINT_STRUCT.TEXTURE_INDEX)] = rotate;\n }\n\n /** Changes the `animX`, `animCountX` of the last tile. */\n tileAnimX(offset: number, count: number): void\n {\n const pb = this.pointsBuf;\n\n pb[pb.length - (POINT_STRUCT_SIZE - POINT_STRUCT.ANIM_X)] = offset;\n pb[pb.length - (POINT_STRUCT_SIZE - POINT_STRUCT.ANIM_COUNT_X)] = count;\n }\n\n /** Changes the `animY`, `animCountY` of the last tile. */\n tileAnimY(offset: number, count: number): void\n {\n const pb = this.pointsBuf;\n\n pb[pb.length - (POINT_STRUCT_SIZE - POINT_STRUCT.ANIM_Y)] = offset;\n pb[pb.length - (POINT_STRUCT_SIZE - POINT_STRUCT.ANIM_COUNT_Y)] = count;\n }\n\n tileAlpha(alpha: number): void\n {\n const pb = this.pointsBuf;\n\n pb[pb.length - (POINT_STRUCT_SIZE - POINT_STRUCT.ALPHA)] = alpha;\n }\n\n renderCanvas = (renderer: CanvasRenderer): void =>\n {\n const plugin = renderer.plugins.tilemap;\n\n if (plugin && !plugin.dontUseTransform)\n {\n const wt = this.worldTransform;\n\n renderer.context.setTransform(\n wt.a,\n wt.b,\n wt.c,\n wt.d,\n wt.tx * renderer.resolution,\n wt.ty * renderer.resolution\n );\n }\n\n this.renderCanvasCore(renderer);\n }\n\n renderCanvasCore(renderer: CanvasRenderer): void\n {\n if (this.tileset.length === 0) return;\n const points = this.pointsBuf;\n const tileAnim = this.tileAnim || (renderer.plugins.tilemap && renderer.plugins.tilemap.tileAnim);\n\n renderer.context.fillStyle = '#000000';\n for (let i = 0, n = points.length; i < n; i += POINT_STRUCT_SIZE)\n {\n let x1 = points[i + POINT_STRUCT.U] * tileAnim[0];\n let y1 = points[i + POINT_STRUCT.V] * tileAnim[1];\n const x2 = points[i + POINT_STRUCT.X];\n const y2 = points[i + POINT_STRUCT.Y];\n const w = points[i + POINT_STRUCT.TILE_WIDTH];\n const h = points[i + POINT_STRUCT.TILE_HEIGHT];\n\n x1 += points[i + POINT_STRUCT.ANIM_X] * renderer.plugins.tilemap.tileAnim[0];\n y1 += points[i + POINT_STRUCT.ANIM_Y] * renderer.plugins.tilemap.tileAnim[1];\n\n const textureIndex = points[i + POINT_STRUCT.TEXTURE_INDEX];\n const alpha = points[i + POINT_STRUCT.ALPHA];\n\n // canvas does not work with rotate yet\n\n if (textureIndex >= 0 && this.tileset[textureIndex])\n {\n renderer.context.globalAlpha = alpha;\n renderer.context.drawImage(\n (this.tileset[textureIndex] as any).getDrawableSource(),\n x1, y1, w, h, x2, y2, w, h\n );\n }\n else\n {\n renderer.context.globalAlpha = 0.5;\n renderer.context.fillRect(x2, y2, w, h);\n }\n renderer.context.globalAlpha = 1;\n }\n }\n\n private vbId = 0;\n private vb: TilemapGeometry = null;\n private vbBuffer: ArrayBuffer = null;\n private vbArray: Float32Array = null;\n private vbInts: Uint32Array = null;\n\n private destroyVb(): void\n {\n if (this.vb)\n {\n this.vb.destroy();\n this.vb = null;\n }\n }\n\n render(renderer: Renderer): void\n {\n const plugin = (renderer.plugins as any).tilemap;\n const shader = plugin.getShader();\n\n renderer.batch.setObjectRenderer(plugin);\n this._globalMat = shader.uniforms.projTransMatrix;\n renderer\n .globalUniforms\n .uniforms\n .projectionMatrix\n .copyTo(this._globalMat)\n .append(this.worldTransform);\n\n shader.uniforms.shadowColor = this.shadowColor;\n shader.uniforms.animationFrame = this.tileAnim || plugin.tileAnim;\n\n this.renderWebGLCore(renderer, plugin);\n }\n\n renderWebGLCore(renderer: Renderer, plugin: TileRenderer): void\n {\n const points = this.pointsBuf;\n\n if (points.length === 0) return;\n const rectsCount = points.length / POINT_STRUCT_SIZE;\n\n const shader = plugin.getShader();\n const textures = this.tileset;\n\n if (textures.length === 0) return;\n\n plugin.bindTileTextures(renderer, textures);\n renderer.shader.bind(shader, false);\n\n // lost context! recover!\n let vb = this.vb;\n\n if (!vb)\n {\n vb = plugin.createVb();\n this.vb = vb;\n this.vbId = (vb as any).id;\n this.vbBuffer = null;\n this.modificationMarker = 0;\n }\n\n plugin.checkIndexBuffer(rectsCount, vb);\n const boundCountPerBuffer = settings.TEXTILE_UNITS;\n\n const vertexBuf = vb.getBuffer('aVertexPosition');\n // if layer was changed, re-upload vertices\n const vertices = rectsCount * vb.vertPerQuad;\n\n if (vertices === 0) return;\n if (this.modificationMarker !== vertices)\n {\n this.modificationMarker = vertices;\n const vs = vb.stride * vertices;\n\n if (!this.vbBuffer || this.vbBuffer.byteLength < vs)\n {\n // !@#$ happens, need resize\n let bk = vb.stride;\n\n while (bk < vs)\n {\n bk *= 2;\n }\n this.vbBuffer = new ArrayBuffer(bk);\n this.vbArray = new Float32Array(this.vbBuffer);\n this.vbInts = new Uint32Array(this.vbBuffer);\n vertexBuf.update(this.vbBuffer);\n }\n\n const arr = this.vbArray;\n // const ints = this.vbInts;\n // upload vertices!\n let sz = 0;\n // let tint = 0xffffffff;\n let textureId = 0;\n let shiftU: number = this.offsetX;\n let shiftV: number = this.offsetY;\n\n // let tint = 0xffffffff;\n // const tint = -1;\n\n for (let i = 0; i < points.length; i += POINT_STRUCT_SIZE)\n {\n const eps = 0.5;\n\n if (this.compositeParent)\n {\n const textureIndex = points[i + POINT_STRUCT.TEXTURE_INDEX];\n\n if (boundCountPerBuffer > 1)\n {\n // TODO: what if its more than 4?\n textureId = (textureIndex >> 2);\n shiftU = this.offsetX * (textureIndex & 1);\n shiftV = this.offsetY * ((textureIndex >> 1) & 1);\n }\n else\n {\n textureId = textureIndex;\n shiftU = 0;\n shiftV = 0;\n }\n }\n const x = points[i + POINT_STRUCT.X];\n const y = points[i + POINT_STRUCT.Y];\n const w = points[i + POINT_STRUCT.TILE_WIDTH];\n const h = points[i + POINT_STRUCT.TILE_HEIGHT];\n const u = points[i + POINT_STRUCT.U] + shiftU;\n const v = points[i + POINT_STRUCT.V] + shiftV;\n let rotate = points[i + POINT_STRUCT.ROTATE];\n\n const animX = points[i + POINT_STRUCT.ANIM_X];\n const animY = points[i + POINT_STRUCT.ANIM_Y];\n const animWidth = points[i + POINT_STRUCT.ANIM_COUNT_X] || 1024;\n const animHeight = points[i + POINT_STRUCT.ANIM_COUNT_Y] || 1024;\n\n const animXEncoded = animX + (animWidth * 2048);\n const animYEncoded = animY + (animHeight * 2048);\n const alpha = points[i + POINT_STRUCT.ALPHA];\n let u0: number;\n let v0: number; let u1: number;\n let v1: number; let u2: number;\n let v2: number; let u3: number;\n let v3: number;\n\n if (rotate === 0)\n {\n u0 = u;\n v0 = v;\n u1 = u + w;\n v1 = v;\n u2 = u + w;\n v2 = v + h;\n u3 = u;\n v3 = v + h;\n }\n else\n {\n let w2 = w / 2;\n let h2 = h / 2;\n\n if (rotate % 4 !== 0)\n {\n w2 = h / 2;\n h2 = w / 2;\n }\n const cX = u + w2;\n const cY = v + h2;\n\n rotate = groupD8.add(rotate, groupD8.NW);\n u0 = cX + (w2 * groupD8.uX(rotate));\n v0 = cY + (h2 * groupD8.uY(rotate));\n\n rotate = groupD8.add(rotate, 2); // rotate 90 degrees clockwise\n u1 = cX + (w2 * groupD8.uX(rotate));\n v1 = cY + (h2 * groupD8.uY(rotate));\n\n rotate = groupD8.add(rotate, 2);\n u2 = cX + (w2 * groupD8.uX(rotate));\n v2 = cY + (h2 * groupD8.uY(rotate));\n\n rotate = groupD8.add(rotate, 2);\n u3 = cX + (w2 * groupD8.uX(rotate));\n v3 = cY + (h2 * groupD8.uY(rotate));\n }\n\n arr[sz++] = x;\n arr[sz++] = y;\n arr[sz++] = u0;\n arr[sz++] = v0;\n arr[sz++] = u + eps;\n arr[sz++] = v + eps;\n arr[sz++] = u + w - eps;\n arr[sz++] = v + h - eps;\n arr[sz++] = animXEncoded;\n arr[sz++] = animYEncoded;\n arr[sz++] = textureId;\n arr[sz++] = alpha;\n\n arr[sz++] = x + w;\n arr[sz++] = y;\n arr[sz++] = u1;\n arr[sz++] = v1;\n arr[sz++] = u + eps;\n arr[sz++] = v + eps;\n arr[sz++] = u + w - eps;\n arr[sz++] = v + h - eps;\n arr[sz++] = animXEncoded;\n arr[sz++] = animYEncoded;\n arr[sz++] = textureId;\n arr[sz++] = alpha;\n\n arr[sz++] = x + w;\n arr[sz++] = y + h;\n arr[sz++] = u2;\n arr[sz++] = v2;\n arr[sz++] = u + eps;\n arr[sz++] = v + eps;\n arr[sz++] = u + w - eps;\n arr[sz++] = v + h - eps;\n arr[sz++] = animXEncoded;\n arr[sz++] = animYEncoded;\n arr[sz++] = textureId;\n arr[sz++] = alpha;\n\n arr[sz++] = x;\n arr[sz++] = y + h;\n arr[sz++] = u3;\n arr[sz++] = v3;\n arr[sz++] = u + eps;\n arr[sz++] = v + eps;\n arr[sz++] = u + w - eps;\n arr[sz++] = v + h - eps;\n arr[sz++] = animXEncoded;\n arr[sz++] = animYEncoded;\n arr[sz++] = textureId;\n arr[sz++] = alpha;\n }\n\n vertexBuf.update(arr);\n }\n\n (renderer.geometry as any).bind(vb, shader);\n renderer.geometry.draw(DRAW_MODES.TRIANGLES, rectsCount * 6, 0);\n }\n\n /**\n * @internal\n * @ignore\n */\n isModified(anim: boolean): boolean\n {\n if (this.modificationMarker !== this.pointsBuf.length\n || (anim && this.hasAnimatedTile))\n {\n return true;\n }\n\n return false;\n }\n\n /**\n * This will pull forward the modification marker.\n *\n * @internal\n * @ignore\n */\n clearModify(): void\n {\n this.modificationMarker = this.pointsBuf.length;\n }\n\n /** @override */\n protected _calculateBounds(): void\n {\n const { minX, minY, maxX, maxY } = this.tilemapBounds;\n\n this._bounds.addFrame(this.transform, minX, minY, maxX, maxY);\n }\n\n /** @override */\n public getLocalBounds(rect?: Rectangle): Rectangle\n {\n // we can do a fast local bounds if the sprite has no children!\n if (this.children.length === 0)\n {\n return this.tilemapBounds.getRectangle(rect);\n }\n\n return super.getLocalBounds.call(this, rect);\n }\n\n /** @override */\n destroy(options?: IDestroyOptions): void\n {\n super.destroy(options);\n this.destroyVb();\n }\n\n /**\n * Deprecated signature for {@link Tilemap.tile tile}.\n *\n * @deprecated Since @pixi/tilemap 3.\n */\n addFrame(texture: Texture | string | number, x: number, y: number, animX: number, animY: number): boolean\n {\n this.tile(\n texture,\n x,\n y,\n {\n animX,\n animY,\n }\n );\n\n return true;\n }\n\n /**\n * Deprecated signature for {@link Tilemap.tile tile}.\n *\n * @deprecated Since @pixi/tilemap 3.\n */\n // eslint-disable-next-line max-params\n addRect(\n textureIndex: number,\n u: number,\n v: number,\n x: number,\n y: number,\n tileWidth: number,\n tileHeight: number,\n animX = 0,\n animY = 0,\n rotate = 0,\n animCountX = 1024,\n animCountY = 1024,\n alpha = 1,\n ): this\n {\n return this.tile(\n textureIndex,\n x, y,\n {\n u, v, tileWidth, tileHeight, animX, animY, rotate, animCountX, animCountY, alpha\n }\n );\n }\n}\n","import { Container } from '@pixi/display';\nimport { Texture, Renderer, BaseTexture } from '@pixi/core';\nimport { Matrix } from '@pixi/math';\nimport { Tilemap } from './Tilemap';\nimport { settings } from './settings';\n\nimport type { CanvasRenderer } from '@pixi/canvas-renderer';\nimport type { TileRenderer } from './TileRenderer';\n\n/**\n * A tilemap composite that lazily builds tilesets layered into multiple tilemaps.\n *\n * The composite tileset is the concatenatation of the individual tilesets used in the tilemaps. You can\n * preinitialized it by passing a list of tile textures to the constructor. Otherwise, the composite tilemap\n * is lazily built as you add more tiles with newer tile textures. A new tilemap is created once the last\n * tilemap has reached its limit (as set by {@link CompositeTilemap.texturesPerTilemap texturesPerTilemap}).\n *\n * @example\n * import { Application } from '@pixi/app';\n * import { CompositeTilemap } from '@pixi/tilemap';\n * import { Loader } from '@pixi/loaders';\n *\n * // Setup view & stage.\n * const app = new Application();\n *\n * document.body.appendChild(app.renderer.view);\n * app.stage.interactive = true;\n *\n * // Global reference to the tilemap.\n * let globalTilemap: CompositeTilemap;\n *\n * // Load the tileset spritesheet!\n * Loader.shared.load('atlas.json');\n *\n * // Initialize the tilemap scene when the assets load.\n * Loader.shared.load(function onTilesetLoaded()\n * {\n * const tilemap = new CompositeTilemap();\n *\n * // Setup the game level with grass and dungeons!\n * for (let x = 0; x < 10; x++)\n * {\n * for (let y = 0; y < 10; y++)\n * {\n * tilemap.tile(\n * x % 2 === 0 && (x === y || x + y === 10) ? 'dungeon.png' : 'grass.png',\n * x * 100,\n * y * 100,\n * );\n * }\n * }\n *\n * globalTilemap = app.stage.addChild(tilemap);\n * });\n *\n * // Show a bomb at a random location whenever the user clicks!\n * app.stage.on('click', function onClick()\n * {\n * if (!globalTilemap) return;\n *\n * const x = Math.floor(Math.random() * 10);\n * const y = Math.floor(Math.random() * 10);\n *\n * globalTilemap.tile('bomb.png', x * 100, y * 100);\n * });\n */\nexport class CompositeTilemap extends Container\n{\n /** The hard limit on the number of tile textures used in each tilemap. */\n public readonly texturesPerTilemap: number;\n\n /**\n * The animation frame vector.\n *\n * Animated tiles have four parameters - `animX`, `animY`, `animCountX`, `animCountY`. The textures\n * of adjacent animation frames are at offset `animX` or `animY` of each other, with `animCountX` per\n * row and `animCountY` per column.\n *\n * The animation frame vector specifies which animation frame texture to use. If the x/y coordinate is\n * larger than the `animCountX` or `animCountY` for a specific tile, the modulus is taken.\n */\n public tileAnim: [number, number] = null;\n\n /** The last modified tilemap. */\n protected lastModifiedTilemap: Tilemap = null;\n\n private modificationMarker = 0;\n private shadowColor = new Float32Array([0.0, 0.0, 0.0, 0.5]);\n private _globalMat: Matrix = null;\n\n /**\n * @param tileset - A list of tile base-textures that will be used to eagerly initialized the layered\n * tilemaps. This is only an performance optimization, and using {@link CompositeTilemap.tile tile}\n * will work equivalently.\n */\n constructor(tileset?: Array)\n {\n super();\n\n this.tileset(tileset);\n this.texturesPerTilemap = settings.TEXTURES_PER_TILEMAP;\n }\n\n /**\n * This will preinitialize the tilesets of the layered tilemaps.\n *\n * If used after a tilemap has been created (or a tile added), this will overwrite the tile textures of the\n * existing tilemaps. Passing the tileset to the constructor instead is the best practice.\n *\n * @param tileTextures - The list of tile textures that make up the tileset.\n */\n tileset(tileTextures: Array): this\n {\n if (!tileTextures)\n {\n tileTextures = [];\n }\n\n const texPerChild = this.texturesPerTilemap;\n const len1 = this.children.length;\n const len2 = Math.ceil(tileTextures.length / texPerChild);\n\n for (let i = 0; i < Math.min(len1, len2); i++)\n {\n (this.children[i] as Tilemap).setTileset(\n tileTextures.slice(i * texPerChild, (i + 1) * texPerChild)\n );\n }\n for (let i = len1; i < len2; i++)\n {\n const tilemap = new Tilemap(tileTextures.slice(i * texPerChild, (i + 1) * texPerChild));\n\n tilemap.compositeParent = true;\n tilemap.offsetX = settings.TEXTILE_DIMEN;\n tilemap.offsetY = settings.TEXTILE_DIMEN;\n\n // TODO: Don't use children\n this.addChild(tilemap);\n }\n\n return this;\n }\n\n /** Clears the tilemap composite. */\n clear(): this\n {\n for (let i = 0; i < this.children.length; i++)\n {\n (this.children[i] as Tilemap).clear();\n }\n\n this.modificationMarker = 0;\n\n return this;\n }\n\n /** Changes the rotation of the last added tile. */\n tileRotate(rotate: number): this\n {\n if (this.lastModifiedTilemap)\n {\n this.lastModifiedTilemap.tileRotate(rotate);\n }\n\n return this;\n }\n\n /** Changes `animX`, `animCountX` of the last added tile. */\n tileAnimX(offset: number, count: number): this\n {\n if (this.lastModifiedTilemap)\n {\n this.lastModifiedTilemap.tileAnimX(offset, count);\n }\n\n return this;\n }\n\n /** Changes `animY`, `animCountY` of the last added tile. */\n tileAnimY(offset: number, count: number): this\n {\n if (this.lastModifiedTilemap)\n {\n this.lastModifiedTilemap.tileAnimY(offset, count);\n }\n\n return this;\n }\n\n /**\n * Adds a tile that paints the given tile texture at (x, y).\n *\n * @param tileTexture - The tile texture. You can pass an index into the composite tilemap as well.\n * @param x - The local x-coordinate of the tile's location.\n * @param y - The local y-coordinate of the tile's location.\n * @param options - Additional options to pass to {@link Tilemap.tile}.\n * @param [options.u=texture.frame.x] - The x-coordinate of the texture in its base-texture's space.\n * @param [options.v=texture.frame.y] - The y-coordinate of the texture in its base-texture's space.\n * @param [options.tileWidth=texture.orig.width] - The local width of the tile.\n * @param [options.tileHeight=texture.orig.height] - The local height of the tile.\n * @param [options.animX=0] - For animated tiles, this is the \"offset\" along the x-axis for adjacent\n * animation frame textures in the base-texture.\n * @param [options.animY=0] - For animated tiles, this is the \"offset\" along the y-axis for adjacent\n * animation frames textures in the base-texture.\n * @param [options.rotate=0]\n * @param [options.animCountX=1024] - For animated tiles, this is the number of animation frame textures\n * per row.\n * @param [options.animCountY=1024] - For animated tiles, this is the number of animation frame textures\n * per column.\n * @param [options.alpha=1] - Tile alpha\n * @return This tilemap, good for chaining.\n */\n tile(\n tileTexture: Texture | string | number,\n x: number,\n y: number,\n options: {\n u?: number,\n v?: number,\n tileWidth?: number,\n tileHeight?: number,\n animX?: number,\n animY?: number,\n rotate?: number,\n animCountX?: number,\n animCountY?: number,\n alpha?: number,\n } = {}\n ): this\n {\n let tilemap: Tilemap = null;\n const children = this.children;\n\n this.lastModifiedTilemap = null;\n\n if (typeof tileTexture === 'number')\n {\n const childIndex = tileTexture / this.texturesPerTilemap >> 0;\n let tileIndex = 0;\n\n tilemap = children[childIndex] as Tilemap;\n\n if (!tilemap)\n {\n tilemap = children[0] as Tilemap;\n\n // Silently fail if the tilemap doesn't exist\n if (!tilemap) return this;\n\n tileIndex = 0;\n }\n else\n {\n tileIndex = tileTexture % this.texturesPerTilemap;\n }\n\n tilemap.tile(\n tileIndex,\n x,\n y,\n options,\n );\n }\n else\n {\n if (typeof tileTexture === 'string')\n {\n tileTexture = Texture.from(tileTexture);\n }\n\n // Probe all tilemaps to find which tileset contains the base-texture.\n for (let i = 0; i < children.length; i++)\n {\n const child = children[i] as Tilemap;\n const tex = child.getTileset();\n\n for (let j = 0; j < tex.length; j++)\n {\n if (tex[j] === tileTexture.baseTexture)\n {\n tilemap = child;\n break;\n }\n }\n\n if (tilemap)\n {\n break;\n }\n }\n\n // If no tileset contains the base-texture, attempt to add it.\n if (!tilemap)\n {\n // Probe the tilemaps to find one below capacity. If so, add the texture into that tilemap.\n for (let i = children.length - 1; i >= 0; i--)\n {\n const child = children[i] as Tilemap;\n\n if (child.getTileset().length < this.texturesPerTilemap)\n {\n tilemap = child;\n child.getTileset().push(tileTexture.baseTexture);\n break;\n }\n }\n\n // Otherwise, create a new tilemap initialized with that tile texture.\n if (!tilemap)\n {\n tilemap = new Tilemap(tileTexture.baseTexture);\n tilemap.compositeParent = true;\n tilemap.offsetX = settings.TEXTILE_DIMEN;\n tilemap.offsetY = settings.TEXTILE_DIMEN;\n\n this.addChild(tilemap);\n }\n }\n\n tilemap.tile(\n tileTexture,\n x,\n y,\n options,\n );\n }\n\n this.lastModifiedTilemap = tilemap;\n\n return this;\n }\n\n renderCanvas = (renderer: CanvasRenderer): void =>\n {\n if (!this.visible || this.worldAlpha <= 0 || !this.renderable)\n {\n return;\n }\n\n const tilemapPlugin = renderer.plugins.tilemap;\n\n if (tilemapPlugin && !tilemapPlugin.dontUseTransform)\n {\n const wt = this.worldTransform;\n\n renderer.context.setTransform(\n wt.a,\n wt.b,\n wt.c,\n wt.d,\n wt.tx * renderer.resolution,\n wt.ty * renderer.resolution\n );\n }\n\n const layers = this.children;\n\n for (let i = 0; i < layers.length; i++)\n {\n const layer = (layers[i] as Tilemap);\n\n layer.tileAnim = this.tileAnim;\n layer.renderCanvasCore(renderer);\n }\n }\n\n render(renderer: Renderer): void\n {\n if (!this.visible || this.worldAlpha <= 0 || !this.renderable)\n {\n return;\n }\n\n const plugin = renderer.plugins.tilemap as TileRenderer;\n const shader = plugin.getShader();\n\n renderer.batch.setObjectRenderer(plugin);\n\n // TODO: dont create new array, please\n this._globalMat = shader.uniforms.projTransMatrix;\n renderer.globalUniforms.uniforms.projectionMatrix.copyTo(this._globalMat).append(this.worldTransform);\n shader.uniforms.shadowColor = this.shadowColor;\n shader.uniforms.animationFrame = this.tileAnim || plugin.tileAnim;\n\n renderer.shader.bind(shader, false);\n\n const layers = this.children;\n\n for (let i = 0; i < layers.length; i++)\n {\n (layers[i] as Tilemap).renderWebGLCore(renderer, plugin);\n }\n }\n\n /**\n * @internal\n * @ignore\n */\n isModified(anim: boolean): boolean\n {\n const layers = this.children;\n\n if (this.modificationMarker !== layers.length)\n {\n return true;\n }\n for (let i = 0; i < layers.length; i++)\n {\n if ((layers[i] as Tilemap).isModified(anim))\n {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * @internal\n * @ignore\n */\n clearModify(): void\n {\n const layers = this.children;\n\n this.modificationMarker = layers.length;\n for (let i = 0; i < layers.length; i++)\n {\n (layers[i] as Tilemap).clearModify();\n }\n }\n\n /**\n * @deprecated Since @pixi/tilemap 3.\n * @see CompositeTilemap.tile\n */\n addFrame(\n texture: Texture | string | number,\n x: number,\n y: number,\n animX?: number,\n animY?: number,\n animWidth?: number,\n animHeight?: number,\n alpha?: number\n ): this\n {\n return this.tile(\n texture,\n x, y,\n {\n animX,\n animY,\n animCountX: animWidth,\n animCountY: animHeight,\n alpha\n }\n );\n }\n\n /**\n * @deprecated @pixi/tilemap 3\n * @see CompositeTilemap.tile\n */\n // eslint-disable-next-line max-params\n addRect(\n textureIndex: number,\n u: number,\n v: number,\n x: number,\n y: number,\n tileWidth: number,\n tileHeight: number,\n animX?: number,\n animY?: number,\n rotate?: number,\n animWidth?: number,\n animHeight?: number\n ): this\n {\n const childIndex: number = textureIndex / this.texturesPerTilemap >> 0;\n const textureId: number = textureIndex % this.texturesPerTilemap;\n\n if (this.children[childIndex] && (this.children[childIndex] as Tilemap).getTileset())\n {\n this.lastModifiedTilemap = (this.children[childIndex] as Tilemap);\n this.lastModifiedTilemap.addRect(\n textureId, u, v, x, y, tileWidth, tileHeight, animX, animY, rotate, animWidth, animHeight\n );\n }\n else\n {\n this.lastModifiedTilemap = null;\n }\n\n return this;\n }\n\n /**\n * Alias for {@link CompositeTilemap.tileset tileset}.\n *\n * @deprecated Since @pixi/tilemap 3.\n */\n setBitmaps = this.tileset;\n\n /**\n * @deprecated Since @pixi/tilemap 3.\n * @readonly\n * @see CompositeTilemap.texturesPerTilemap\n */\n get texPerChild(): number { return this.texturesPerTilemap; }\n}\n","import { ALPHA_MODES } from '@pixi/constants';\nimport { BaseTexture, Renderer, Resource, Texture, GLTexture } from '@pixi/core';\nimport { settings } from './settings';\n\nexport interface TextileOptions\n{\n\tTEXTILE_DIMEN: number;\n\tTEXTILE_UNITS: number;\n\tDO_CLEAR?: boolean;\n}\n\ntype TextureTile = {\n\tdirtyId: number;\n\tx: number;\n\ty: number;\n\tbaseTexture: BaseTexture;\n};\n\n// For some reason ESLint goes mad with indendation in this file ^&^\n/* eslint-disable indent */\n\n/**\n * This texture tiling resource can be used to upload multiple base-textures together.\n *\n * This resource combines multiple base-textures into a \"textile\". They're laid out in\n * a dual column format, placed in row-order order. The size of each tile is predefined,\n * and defaults to {@link settings.TEXTILE_DIMEN}. This means that each input base-texture\n * must is smaller than that along both its width and height.\n *\n * @see settings.TEXTILE_UNITS\n */\nexport class TextileResource extends Resource\n{\n\t/** The base-texture that contains all the texture tiles. */\n\tpublic baseTexture: BaseTexture = null;\n\n\tprivate readonly doClear: boolean;\n\tprivate readonly tileDimen: number;\n\tprivate readonly tiles: Array;\n\n\tprivate _clearBuffer: Uint8Array = null;\n\n\t/**\n\t * @param options - This will default to the \"settings\" exported by @pixi/tilemap.\n\t * @param options.TEXTILE_DIMEN - The dimensions of each tile.\n\t * @param options.TEXTILE_UNITS - The number of texture tiles.\n\t */\n\tconstructor(options: TextileOptions = settings)\n\t{\n\t\tsuper(\n\t\t\toptions.TEXTILE_DIMEN * 2,\n\t\t\toptions.TEXTILE_DIMEN * Math.ceil(options.TEXTILE_UNITS / 2),\n\t\t);\n\n\t\tconst tiles: TextureTile[] = this.tiles = new Array(options.TEXTILE_UNITS);\n\n\t\tthis.doClear = !!options.DO_CLEAR;\n\t\tthis.tileDimen = options.TEXTILE_DIMEN;\n\n\t\tfor (let j = 0; j < options.TEXTILE_UNITS; j++)\n\t\t{\n\t\t\ttiles[j] = {\n\t\t\t\tdirtyId: 0,\n\t\t\t\tx: options.TEXTILE_DIMEN * (j & 1),\n\t\t\t\ty: options.TEXTILE_DIMEN * (j >> 1),\n\t\t\t\tbaseTexture: Texture.WHITE.baseTexture,\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Sets the texture to be uploaded for the given tile.\n\t *\n\t * @param index - The index of the tile being set.\n\t * @param texture - The texture with the base-texture to upload.\n\t */\n\ttile(index: number, texture: BaseTexture): void\n\t{\n\t\tconst tile = this.tiles[index];\n\n\t\tif (tile.baseTexture === texture)\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\ttile.baseTexture = texture;\n\t\tthis.baseTexture.update();\n\n\t\tthis.tiles[index].dirtyId = (this.baseTexture as any).dirtyId;\n\t}\n\n\t/** @override */\n\tbind(baseTexture: BaseTexture): void\n\t{\n\t\tif (this.baseTexture)\n\t\t{\n\t\t\tthrow new Error('Only one baseTexture is allowed for this resource!');\n\t\t}\n\n\t\tthis.baseTexture = baseTexture;\n\t\tsuper.bind(baseTexture);\n\t}\n\n\t/** @override */\n\tupload(renderer: Renderer, texture: BaseTexture, glTexture: GLTexture): boolean\n\t{\n\t\tconst { gl } = renderer;\n\t\tconst { width, height } = this;\n\n\t\tgl.pixelStorei(\n\t\t\tgl.UNPACK_PREMULTIPLY_ALPHA_WEBGL,\n\t\t\ttexture.alphaMode === undefined || texture.alphaMode === ALPHA_MODES.UNPACK\n\t\t);\n\n\t\tif (glTexture.dirtyId < 0)\n\t\t{\n\t\t\t(glTexture as any).width = width;\n\t\t\t(glTexture as any).height = height;\n\n\t\t\tgl.texImage2D(texture.target, 0,\n\t\t\t\ttexture.format,\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\t0,\n\t\t\t\ttexture.format,\n\t\t\t\ttexture.type,\n\t\t\t\tnull);\n\t\t}\n\n\t\tconst doClear = this.doClear;\n\t\tconst tiles = this.tiles;\n\n\t\tif (doClear && !this._clearBuffer)\n\t\t{\n\t\t\tthis._clearBuffer = new Uint8Array(settings.TEXTILE_DIMEN * settings.TEXTILE_DIMEN * 4);\n\t\t}\n\n\t\tfor (let i = 0; i < tiles.length; i++)\n\t\t{\n\t\t\tconst spr = tiles[i];\n\t\t\tconst tex = spr.baseTexture;\n\n\t\t\tif (glTexture.dirtyId >= this.tiles[i].dirtyId)\n\t\t\t{\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst res = tex.resource as any;\n\n\t\t\tif (!tex.valid || !res || !res.source)\n\t\t\t{\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (doClear && (tex.width < this.tileDimen || tex.height < this.tileDimen))\n\t\t\t{\n\t\t\t\tgl.texSubImage2D(texture.target, 0,\n\t\t\t\t\tspr.x,\n\t\t\t\t\tspr.y,\n\t\t\t\t\tthis.tileDimen,\n\t\t\t\t\tthis.tileDimen,\n\t\t\t\t\ttexture.format,\n\t\t\t\t\ttexture.type,\n\t\t\t\t\tthis._clearBuffer);\n\t\t\t}\n\n\t\t\tgl.texSubImage2D(texture.target, 0,\n\t\t\t\tspr.x,\n\t\t\t\tspr.y,\n\t\t\t\ttexture.format,\n\t\t\t\ttexture.type,\n\t\t\t\tres.source);\n\t\t}\n\n\t\treturn true;\n\t}\n}\n","import type { TilemapShader } from './TilemapShader';\n\n/**\n * This will generate fragment shader code that samples the correct texture into the \"color\" variable.\n *\n * @internal\n * @ignore\n * @param maxTextures - The texture array length in the shader's uniforms.\n */\nfunction generateSampleSrc(maxTextures: number): string\n{\n let src = '';\n\n src += '\\n';\n src += '\\n';\n\n src += 'if(vTextureId <= -1.0) {';\n src += '\\n\\tcolor = shadowColor;';\n src += '\\n}';\n\n for (let i = 0; i < maxTextures; i++)\n {\n src += '\\nelse ';\n\n if (i < maxTextures - 1)\n {\n src += `if(textureId == ${i}.0)`;\n }\n\n src += '\\n{';\n src += `\\n\\tcolor = texture2D(uSamplers[${i}], textureCoord * uSamplerSize[${i}]);`;\n src += '\\n}';\n }\n\n src += '\\n';\n src += '\\n';\n\n return src;\n}\n\n/**\n * @internal\n * @ignore\n * @param shader\n * @param maxTextures\n */\nexport function fillSamplers(shader: TilemapShader, maxTextures: number): void\n{\n const sampleValues: Array = [];\n\n for (let i = 0; i < maxTextures; i++)\n {\n sampleValues[i] = i;\n }\n\n shader.uniforms.uSamplers = sampleValues;\n\n const samplerSize: Array = [];\n\n for (let i = 0; i < maxTextures; i++)\n {\n // These are overwritten by TileRenderer when textures actually bound.\n samplerSize.push(1.0 / 2048);\n samplerSize.push(1.0 / 2048);\n }\n\n shader.uniforms.uSamplerSize = samplerSize;\n}\n\n/**\n * @internal\n * @ignore\n * @param maxTextures\n * @param fragmentSrc\n * @returns\n */\nexport function generateFragmentSrc(maxTextures: number, fragmentSrc: string): string\n{\n return fragmentSrc.replace(/%count%/gi, `${maxTextures}`)\n .replace(/%forloop%/gi, generateSampleSrc(maxTextures));\n}\n","// eslint-disable-next-line @typescript-eslint/triple-slash-reference, spaced-comment\n///\n\nimport * as shaderGenerator from './shaderGenerator';\nimport tilemapVertexTemplateSrc from './tilemap.vert';\nimport tilemapFragmentTemplateSrc from './tilemap.frag';\n\nimport { Buffer, Geometry, Shader, Program } from '@pixi/core';\nimport { Matrix } from '@pixi/math';\n\n// For some reason ESLint goes mad with indendation in this file ^&^\n/* eslint-disable no-mixed-spaces-and-tabs, indent */\n\nexport class TilemapShader extends Shader\n{\n\tmaxTextures = 0;\n\n\tconstructor(maxTextures: number)\n\t{\n\t super(\n\t new Program(\n\t\t\t\ttilemapVertexTemplateSrc,\n\t\t\t\tshaderGenerator.generateFragmentSrc(maxTextures, tilemapFragmentTemplateSrc)\n\t\t\t),\n\t {\n\t animationFrame: new Float32Array(2),\n\t uSamplers: [],\n\t uSamplerSize: [],\n\t projTransMatrix: new Matrix()\n\t }\n\t );\n\n\t this.maxTextures = maxTextures;\n\t shaderGenerator.fillSamplers(this, this.maxTextures);\n\t}\n}\n\nexport class TilemapGeometry extends Geometry\n{\n\tvertSize = 12;\n\tvertPerQuad = 4;\n\tstride = this.vertSize * 4;\n\tlastTimeAccess = 0;\n\n\tconstructor()\n\t{\n\t super();\n\n\t const buf = this.buf = new Buffer(new Float32Array(2), true, false);\n\n\t this.addAttribute('aVertexPosition', buf, 0, false, 0, this.stride, 0)\n\t .addAttribute('aTextureCoord', buf, 0, false, 0, this.stride, 2 * 4)\n\t .addAttribute('aFrame', buf, 0, false, 0, this.stride, 4 * 4)\n\t .addAttribute('aAnim', buf, 0, false, 0, this.stride, 8 * 4)\n\t .addAttribute('aTextureId', buf, 0, false, 0, this.stride, 10 * 4)\n .addAttribute('aAlpha', buf, 0, false, 0, this.stride, 11 * 4);\n\t}\n\n\tbuf: Buffer;\n}\n","import { WRAP_MODES } from '@pixi/constants';\nimport { BaseTexture, Buffer, ObjectRenderer, Renderer } from '@pixi/core';\nimport { settings } from './settings';\nimport { TilemapGeometry, TilemapShader } from './TilemapShader';\nimport { TextileResource } from './TextileResource';\nimport * as utils from '@pixi/utils';\n\n// For some reason ESLint goes mad with indendation in this file ^&^\n/* eslint-disable no-mixed-spaces-and-tabs, indent */\n\n/**\n * Rendering helper pipeline for tilemaps. This plugin is registered automatically.\n */\nexport class TileRenderer extends ObjectRenderer\n{\n\t/** The managing renderer */\n\tpublic readonly renderer: Renderer;\n\n\t/** The tile animation frame */\n\tpublic tileAnim = [0, 0];\n\n\tprivate ibLen = 0;// index buffer length\n\n\t/** The index buffer for the tilemaps to share. */\n\tprivate indexBuffer: Buffer = null;\n\n\t/** The shader used to render tilemaps. */\n\tprivate shader: TilemapShader;\n\n\t/**\n\t * {@link TextileResource} instances used to upload textures batched in tiled groups. This is\n\t * used only if {@link settings.TEXTURES_PER_TILEMAP} is greater than 1.\n\t */\n\tprivate textiles: Array = [];\n\n\t/** @param renderer - The managing renderer */\n\tconstructor(renderer: Renderer)\n\t{\n\t super(renderer);\n\n\t this.shader = new TilemapShader(settings.TEXTURES_PER_TILEMAP);\n\t this.indexBuffer = new Buffer(undefined, true, true);\n\t this.checkIndexBuffer(2000);\n\t this.makeTextiles();\n\t}\n\n\t/**\n\t * Binds the tile textures to the renderer, and updates the tilemap shader's `uSamplerSize` uniform.\n\t *\n\t * If {@link settings.TEXTILE_UNITS}\n\t *\n\t * @param renderer - The renderer to which the textures are to be bound.\n\t * @param textures - The tile textures being bound.\n\t */\n\tbindTileTextures(renderer: Renderer, textures: Array): void\n\t{\n\t const len = textures.length;\n\t\tconst shader = this.shader;\n\t const maxTextures = settings.TEXTURES_PER_TILEMAP;\n\t\tconst samplerSize: Array = shader.uniforms.uSamplerSize;\n\n\t if (len > settings.TEXTILE_UNITS * maxTextures)\n\t {\n\t\t\t// TODO: Show error message instead of silently failing!\n\t return;\n\t }\n\n\t\tif (settings.TEXTILE_UNITS <= 1)\n\t {\n\t\t\t// Bind each texture directly & update samplerSize.\n\t\t\tfor (let i = 0; i < textures.length; i++)\n\t\t\t{\n\t\t\t\tconst texture = textures[i];\n\n\t\t\t\tif (!texture || !texture.valid)\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\trenderer.texture.bind(textures[i], i);\n\n\t\t\t\tsamplerSize[i * 2] = 1.0 / textures[i].realWidth;\n\t\t\t\tsamplerSize[(i * 2) + 1] = 1.0 / textures[i].realHeight;\n\t\t\t}\n\t }\n\t\telse\n\t\t{\n\t\t\t// Ensure we have enough textiles, in case settings.TEXTILE_UNITS was modified.\n\t\t\tthis.makeTextiles();\n\n\t\t\tconst usedTextiles = Math.ceil(len / settings.TEXTILE_UNITS);\n\n\t\t\t// First ensure each textile has all tiles point to the right textures.\n\t\t\tfor (let i = 0; i < len; i++)\n\t\t\t{\n\t\t\t\tconst texture = textures[i];\n\n\t\t\t\tif (texture && texture.valid)\n\t\t\t\t{\n\t\t\t\t\tconst resourceIndex = Math.floor(i / settings.TEXTILE_UNITS);\n\t\t\t\t\tconst tileIndex = i % settings.TEXTILE_UNITS;\n\n\t\t\t\t\tthis.textiles[resourceIndex].tile(tileIndex, texture);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Then bind the textiles + update samplerSize.\n\t\t\tfor (let i = 0; i < usedTextiles; i++)\n\t\t\t{\n\t\t\t\trenderer.texture.bind(this.textiles[i].baseTexture, i);\n\n\t\t\t\tsamplerSize[i * 2] = 1.0 / this.textiles[i].width;\n\t\t\t\tsamplerSize[(i * 2) + 1] = 1.0 / this.textiles[i].baseTexture.height;\n\t\t\t}\n\t\t}\n\n\t\tshader.uniforms.uSamplerSize = samplerSize;\n\t}\n\n\tstart(): void\n\t{\n\t // sorry, nothing\n\t}\n\n\t/**\n\t * @internal\n\t * @ignore\n\t */\n\tcreateVb(): TilemapGeometry\n\t{\n\t const geom = new TilemapGeometry();\n\n\t geom.addIndex(this.indexBuffer);\n\t geom.lastTimeAccess = Date.now();\n\n\t return geom;\n\t}\n\n\t/** @return The {@link TilemapShader} shader that this rendering pipeline is using. */\n\tgetShader(): TilemapShader { return this.shader; }\n\n\tdestroy(): void\n\t{\n\t super.destroy();\n\t // this.rectShader.destroy();\n\t this.shader = null;\n\t}\n\n\tpublic checkIndexBuffer(size: number, _vb: TilemapGeometry = null): void\n\t{\n\t const totalIndices = size * 6;\n\n\t if (totalIndices <= this.ibLen)\n\t {\n\t return;\n\t }\n\n\t let len = totalIndices;\n\n\t while (len < totalIndices)\n\t {\n\t len <<= 1;\n\t }\n\n\t this.ibLen = totalIndices;\n\t this.indexBuffer.update(utils.createIndicesForQuads(size,\n\t settings.use32bitIndex ? new Uint32Array(size * 6) : undefined));\n\n\t // \tTODO: create new index buffer instead?\n\t // if (vb) {\n\t // \tconst curIndex = vb.getIndex();\n\t // \tif (curIndex !== this.indexBuffer && (curIndex.data as any).length < totalIndices) {\n\t // \t\tthis.swapIndex(vb, this.indexBuffer);\n\t // \t}\n\t // }\n\t}\n\n\t/** Makes textile resources and initializes {@link TileRenderer.textiles}. */\n\tprivate makeTextiles(): void\n\t{\n\t if (settings.TEXTILE_UNITS <= 1)\n\t {\n\t return;\n\t }\n\n\t for (let i = 0; i < settings.TEXTILE_UNITS; i++)\n\t {\n\t\t\tif (this.textiles[i]) continue;\n\n\t\t\tconst resource = new TextileResource();\n\t const baseTex = new BaseTexture(resource);\n\n\t baseTex.scaleMode = settings.TEXTILE_SCALE_MODE;\n\t baseTex.wrapMode = WRAP_MODES.CLAMP;\n\n\t\t\tthis.textiles[i] = resource;\n\t }\n\t}\n}\n\nRenderer.registerPlugin('tilemap', TileRenderer as any);\n","import { CanvasTileRenderer } from './CanvasTileRenderer';\nimport { CompositeTilemap } from './CompositeTilemap';\nimport { Constant } from './settings';\nimport { TextileResource } from './TextileResource';\nimport { Tilemap } from './Tilemap';\nimport { TilemapShader, TilemapGeometry } from './TilemapShader';\nimport { TileRenderer } from './TileRenderer';\n\n// Prevent SCALE_MODES from becoming lazy import in Constant.ts - which causes a import() in the declaration file,\n// which causes API extractor to fail https://github.com/microsoft/rushstack/issues/2140\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport * as constants from '@pixi/constants';\n\n// eslint-disable-next-line camelcase\nexport const pixi_tilemap = {\n CanvasTileRenderer,\n CompositeRectTileLayer: CompositeTilemap,\n CompositeTilemap,\n Constant,\n TextileResource,\n MultiTextureResource: TextileResource,\n RectTileLayer: Tilemap,\n Tilemap,\n TilemapShader,\n TilemapGeometry,\n RectTileShader: TilemapShader,\n RectTileGeom: TilemapGeometry,\n TileRenderer,\n};\n\nexport * from './CanvasTileRenderer';\nexport * from './CompositeTilemap';\nexport * from './settings';\nexport * from './TextileResource';\nexport * from './Tilemap';\nexport * from './TilemapShader';\nexport * from './shaderGenerator';\nexport * from './TileRenderer';\n\nexport { CompositeTilemap as CompositeRectTileLayer } from './CompositeTilemap';\nexport { Tilemap as RectTileLayer } from './Tilemap';\n"],"names":["Renderer"],"mappings":";;;;;;;;;;;;;;;;;;;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAEA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IC9BA;IACA;IACA;IACA;IACA;IACA;;IAEA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;;;uGC7CA;AACA;AACA;AACA;AACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;;AAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAEA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;ICltBA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAEA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IC7eA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAEA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;;IC7KA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAEA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAEA;IACA;IACA;IACA;;;;;;IChFA;AASA;IACA;IACA;AACA;;IAEA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;;IAEA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;;ICpDA;IACA;AACA;IACA;IACA;IACA;;IAEA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;IACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;AACA;IACA;IACA;IACA;IACA;AACA;AACAA;;IC3LA;;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file diff --git a/index.d.ts b/index.d.ts index 62b174c..047d098 100644 --- a/index.d.ts +++ b/index.d.ts @@ -167,7 +167,7 @@ declare class Tilemap extends Container { tileAnimX(offset: number, count: number): void; tileAnimY(offset: number, count: number): void; tileAlpha(alpha: number): void; - renderCanvas(renderer: CanvasRenderer): void; + renderCanvas: (renderer: CanvasRenderer) => void; renderCanvasCore(renderer: CanvasRenderer): void; private vbId; private vb; diff --git a/package.json b/package.json index ad575eb..b6e5697 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@pixi/tilemap", - "version": "2.2.0", + "version": "3.1.0", "description": "A low-level, optimized rectangular tilemap implementation for PixiJS.", "author": "Ivan Popelyshev", "contributors": [