{"version":3,"file":"CanvasMeshRenderer.mjs","sources":["../src/CanvasMeshRenderer.ts"],"sourcesContent":["import { canvasUtils } from '@pixi/canvas-renderer';\nimport { DRAW_MODES, extensions, ExtensionType, Texture } from '@pixi/core';\n\nimport type { CanvasRenderer } from '@pixi/canvas-renderer';\nimport type { ExtensionMetadata } from '@pixi/core';\nimport type { Mesh } from '@pixi/mesh';\n\n/**\n * Renderer dedicated to meshes.\n * @class\n * @protected\n * @memberof PIXI\n */\nexport class CanvasMeshRenderer\n{\n    /** @ignore */\n    static extension: ExtensionMetadata = {\n        name: 'mesh',\n        type: ExtensionType.CanvasRendererPlugin,\n    };\n\n    /** A reference to the current renderer */\n    public renderer: CanvasRenderer;\n\n    /** @param renderer - A reference to the current renderer */\n    constructor(renderer: CanvasRenderer)\n    {\n        this.renderer = renderer;\n    }\n\n    /**\n     * Renders the Mesh\n     * @param mesh - the Mesh to render\n     */\n    public render(mesh: Mesh): void\n    {\n        const renderer = this.renderer;\n        const transform = mesh.worldTransform;\n\n        renderer.canvasContext.activeContext.globalAlpha = mesh.worldAlpha;\n        renderer.canvasContext.setBlendMode(mesh.blendMode);\n        renderer.canvasContext.setContextTransform(transform, mesh.roundPixels);\n\n        if (mesh.drawMode !== DRAW_MODES.TRIANGLES)\n        {\n            this._renderTriangleMesh(mesh);\n        }\n        else\n        {\n            this._renderTriangles(mesh);\n        }\n    }\n\n    /**\n     * Draws the object in Triangle Mesh mode\n     * @private\n     * @param mesh - the Mesh to render\n     */\n    private _renderTriangleMesh(mesh: Mesh): void\n    {\n        // draw triangles!!\n        const length = mesh.geometry.buffers[0].data.length;\n\n        for (let i = 0; i < length - 2; i++)\n        {\n            // draw some triangles!\n            const index = i * 2;\n\n            this._renderDrawTriangle(mesh, index, (index + 2), (index + 4));\n        }\n    }\n\n    /**\n     * Draws the object in triangle mode using canvas\n     * @private\n     * @param mesh - the current mesh\n     */\n    private _renderTriangles(mesh: Mesh): void\n    {\n        // draw triangles!!\n        const indices = mesh.geometry.getIndex().data;\n        const length = indices.length;\n\n        for (let i = 0; i < length; i += 3)\n        {\n            // draw some triangles!\n            const index0 = indices[i] * 2;\n            const index1 = indices[i + 1] * 2;\n            const index2 = indices[i + 2] * 2;\n\n            this._renderDrawTriangle(mesh, index0, index1, index2);\n        }\n    }\n\n    /**\n     * Draws one of the triangles that from the Mesh\n     * @private\n     * @param mesh - the current mesh\n     * @param index0 - the index of the first vertex\n     * @param index1 - the index of the second vertex\n     * @param index2 - the index of the third vertex\n     */\n    private _renderDrawTriangle(mesh: Mesh, index0: number, index1: number, index2: number): void\n    {\n        const context = this.renderer.canvasContext.activeContext;\n        const vertices = mesh.geometry.buffers[0].data;\n        const { uvs, texture } = mesh;\n\n        if (!texture.valid)\n        {\n            return;\n        }\n        const isTinted = mesh.tintValue !== 0xFFFFFF;\n        const base = texture.baseTexture;\n        const textureWidth = base.width;\n        const textureHeight = base.height;\n\n        // Invalidate texture if base texture was updated\n        // either because mesh.texture or mesh.shader.texture was changed\n        if (mesh._cachedTexture && mesh._cachedTexture.baseTexture !== base)\n        {\n            mesh._cachedTint = 0xffffff;\n            mesh._cachedTexture?.destroy();\n            mesh._cachedTexture = null;\n            mesh._tintedCanvas = null;\n        }\n\n        if (isTinted)\n        {\n            if (mesh._cachedTint !== mesh.tintValue)\n            {\n                mesh._cachedTint = mesh.tintValue;\n                mesh._cachedTexture = mesh._cachedTexture || new Texture(base);\n                mesh._tintedCanvas = canvasUtils.getTintedCanvas(\n                    { texture: mesh._cachedTexture },\n                    mesh.tintValue\n                );\n            }\n        }\n\n        const textureSource = isTinted ? mesh._tintedCanvas : base.getDrawableSource();\n\n        const u0 = uvs[index0] * base.width;\n        const u1 = uvs[index1] * base.width;\n        const u2 = uvs[index2] * base.width;\n        const v0 = uvs[index0 + 1] * base.height;\n        const v1 = uvs[index1 + 1] * base.height;\n        const v2 = uvs[index2 + 1] * base.height;\n\n        let x0 = vertices[index0];\n        let x1 = vertices[index1];\n        let x2 = vertices[index2];\n        let y0 = vertices[index0 + 1];\n        let y1 = vertices[index1 + 1];\n        let y2 = vertices[index2 + 1];\n\n        const screenPadding = mesh.canvasPadding / this.renderer.canvasContext.activeResolution;\n\n        if (screenPadding > 0)\n        {\n            const { a, b, c, d } = mesh.worldTransform;\n\n            const centerX = (x0 + x1 + x2) / 3;\n            const centerY = (y0 + y1 + y2) / 3;\n\n            let normX = x0 - centerX;\n            let normY = y0 - centerY;\n\n            // Transform to screen space and calculate the distance\n            let screenX = (a * normX) + (c * normY);\n            let screenY = (b * normX) + (d * normY);\n            let screenDist = Math.sqrt((screenX * screenX) + (screenY * screenY));\n\n            // Factor by which to scale in order to add padding equal to screenPadding\n            let paddingFactor = 1 + (screenPadding / screenDist);\n\n            x0 = centerX + (normX * paddingFactor);\n            y0 = centerY + (normY * paddingFactor);\n\n            normX = x1 - centerX;\n            normY = y1 - centerY;\n\n            screenX = (a * normX) + (c * normY);\n            screenY = (b * normX) + (d * normY);\n            screenDist = Math.sqrt((screenX * screenX) + (screenY * screenY));\n\n            paddingFactor = 1 + (screenPadding / screenDist);\n\n            x1 = centerX + (normX * paddingFactor);\n            y1 = centerY + (normY * paddingFactor);\n\n            normX = x2 - centerX;\n            normY = y2 - centerY;\n\n            screenX = (a * normX) + (c * normY);\n            screenY = (b * normX) + (d * normY);\n            screenDist = Math.sqrt((screenX * screenX) + (screenY * screenY));\n\n            paddingFactor = 1 + (screenPadding / screenDist);\n\n            x2 = centerX + (normX * paddingFactor);\n            y2 = centerY + (normY * paddingFactor);\n        }\n\n        context.save();\n        context.beginPath();\n\n        context.moveTo(x0, y0);\n        context.lineTo(x1, y1);\n        context.lineTo(x2, y2);\n\n        context.closePath();\n\n        context.clip();\n\n        // Compute matrix transform\n        const delta = (u0 * v1) + (v0 * u2) + (u1 * v2) - (v1 * u2) - (v0 * u1) - (u0 * v2);\n        const deltaA = (x0 * v1) + (v0 * x2) + (x1 * v2) - (v1 * x2) - (v0 * x1) - (x0 * v2);\n        const deltaB = (u0 * x1) + (x0 * u2) + (u1 * x2) - (x1 * u2) - (x0 * u1) - (u0 * x2);\n        const deltaC = (u0 * v1 * x2) + (v0 * x1 * u2) + (x0 * u1 * v2) - (x0 * v1 * u2) - (v0 * u1 * x2) - (u0 * x1 * v2);\n        const deltaD = (y0 * v1) + (v0 * y2) + (y1 * v2) - (v1 * y2) - (v0 * y1) - (y0 * v2);\n        const deltaE = (u0 * y1) + (y0 * u2) + (u1 * y2) - (y1 * u2) - (y0 * u1) - (u0 * y2);\n        const deltaF = (u0 * v1 * y2) + (v0 * y1 * u2) + (y0 * u1 * v2) - (y0 * v1 * u2) - (v0 * u1 * y2) - (u0 * y1 * v2);\n\n        context.transform(\n            deltaA / delta,\n            deltaD / delta,\n            deltaB / delta,\n            deltaE / delta,\n            deltaC / delta,\n            deltaF / delta\n        );\n\n        context.drawImage(\n            textureSource,\n            0,\n            0,\n            textureWidth * base.resolution,\n            textureHeight * base.resolution,\n            0,\n            0,\n            textureWidth,\n            textureHeight\n        );\n\n        context.restore();\n        this.renderer.canvasContext.invalidateBlendMode();\n    }\n\n    /**\n     * Renders a flat Mesh\n     * @private\n     * @param mesh - The Mesh to render\n     */\n    renderMeshFlat(mesh: Mesh): void\n    {\n        const context = this.renderer.canvasContext.activeContext;\n        const vertices = mesh.geometry.getBuffer('aVertexPosition').data;\n        const length = vertices.length / 2;\n\n        // this.count++;\n\n        context.beginPath();\n\n        for (let i = 1; i < length - 2; ++i)\n        {\n            // draw some triangles!\n            const index = i * 2;\n\n            const x0 = vertices[index];\n            const y0 = vertices[index + 1];\n\n            const x1 = vertices[index + 2];\n            const y1 = vertices[index + 3];\n\n            const x2 = vertices[index + 4];\n            const y2 = vertices[index + 5];\n\n            context.moveTo(x0, y0);\n            context.lineTo(x1, y1);\n            context.lineTo(x2, y2);\n        }\n\n        context.fillStyle = '#FF0000';\n        context.fill();\n        context.closePath();\n    }\n\n    /** destroy the renderer */\n    public destroy(): void\n    {\n        this.renderer = null;\n    }\n}\n\nextensions.add(CanvasMeshRenderer);\n"],"names":[],"mappings":"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"}