{"version":3,"file":"RopeGeometry.mjs","sources":["../../src/geometry/RopeGeometry.ts"],"sourcesContent":["import { MeshGeometry } from 'pixijs/mesh';\n\nimport type { IPoint } from 'pixijs/core';\n\n/**\n * RopeGeometry allows you to draw a geometry across several points and then manipulate these points.\n * @example\n * import { Point, RopeGeometry } from 'pixijs/browser';\n *\n * for (let i = 0; i < 20; i++) {\n *     points.push(new Point(i * 50, 0));\n * };\n * const rope = new RopeGeometry(100, points);\n * @memberof PIXI\n */\nexport class RopeGeometry extends MeshGeometry\n{\n    /** An array of points that determine the rope. */\n    public points: IPoint[];\n\n    /** Rope texture scale, if zero then the rope texture is stretched. */\n    public readonly textureScale: number;\n\n    /**\n     * The width (i.e., thickness) of the rope.\n     * @readonly\n     */\n    _width: number;\n\n    /**\n     * @param width - The width (i.e., thickness) of the rope.\n     * @param points - An array of {@link PIXI.Point} objects to construct this rope.\n     * @param textureScale - By default the rope texture will be stretched to match\n     *     rope length. If textureScale is positive this value will be treated as a scaling\n     *     factor and the texture will preserve its aspect ratio instead. To create a tiling rope\n     *     set baseTexture.wrapMode to {@link PIXI.WRAP_MODES.REPEAT} and use a power of two texture,\n     *     then set textureScale=1 to keep the original texture pixel size.\n     *     In order to reduce alpha channel artifacts provide a larger texture and downsample -\n     *     i.e. set textureScale=0.5 to scale it down twice.\n     */\n    constructor(width = 200, points: IPoint[], textureScale = 0)\n    {\n        super(new Float32Array(points.length * 4),\n            new Float32Array(points.length * 4),\n            new Uint16Array((points.length - 1) * 6));\n\n        this.points = points;\n        this._width = width;\n        this.textureScale = textureScale;\n\n        this.build();\n    }\n\n    /**\n     * The width (i.e., thickness) of the rope.\n     * @readonly\n     */\n    get width(): number\n    {\n        return this._width;\n    }\n\n    /** Refreshes Rope indices and uvs */\n    private build(): void\n    {\n        const points = this.points;\n\n        if (!points) return;\n\n        const vertexBuffer = this.getBuffer('aVertexPosition');\n        const uvBuffer = this.getBuffer('aTextureCoord');\n        const indexBuffer = this.getIndex();\n\n        // if too little points, or texture hasn't got UVs set yet just move on.\n        if (points.length < 1)\n        {\n            return;\n        }\n\n        // if the number of points has changed we will need to recreate the arraybuffers\n        if (vertexBuffer.data.length / 4 !== points.length)\n        {\n            vertexBuffer.data = new Float32Array(points.length * 4);\n            uvBuffer.data = new Float32Array(points.length * 4);\n            indexBuffer.data = new Uint16Array((points.length - 1) * 6);\n        }\n\n        const uvs = uvBuffer.data;\n        const indices = indexBuffer.data;\n\n        uvs[0] = 0;\n        uvs[1] = 0;\n        uvs[2] = 0;\n        uvs[3] = 1;\n\n        let amount = 0;\n        let prev = points[0];\n        const textureWidth = this._width * this.textureScale;\n        const total = points.length; // - 1;\n\n        for (let i = 0; i < total; i++)\n        {\n            // time to do some smart drawing!\n            const index = i * 4;\n\n            if (this.textureScale > 0)\n            {\n                // calculate pixel distance from previous point\n                const dx = prev.x - points[i].x;\n                const dy = prev.y - points[i].y;\n                const distance = Math.sqrt((dx * dx) + (dy * dy));\n\n                prev = points[i];\n                amount += distance / textureWidth;\n            }\n            else\n            {\n                // stretch texture\n                amount = i / (total - 1);\n            }\n\n            uvs[index] = amount;\n            uvs[index + 1] = 0;\n\n            uvs[index + 2] = amount;\n            uvs[index + 3] = 1;\n        }\n\n        let indexCount = 0;\n\n        for (let i = 0; i < total - 1; i++)\n        {\n            const index = i * 2;\n\n            indices[indexCount++] = index;\n            indices[indexCount++] = index + 1;\n            indices[indexCount++] = index + 2;\n\n            indices[indexCount++] = index + 2;\n            indices[indexCount++] = index + 1;\n            indices[indexCount++] = index + 3;\n        }\n\n        // ensure that the changes are uploaded\n        uvBuffer.update();\n        indexBuffer.update();\n\n        this.updateVertices();\n    }\n\n    /** refreshes vertices of Rope mesh */\n    public updateVertices(): void\n    {\n        const points = this.points;\n\n        if (points.length < 1)\n        {\n            return;\n        }\n\n        let lastPoint = points[0];\n        let nextPoint;\n        let perpX = 0;\n        let perpY = 0;\n\n        const vertices = this.buffers[0].data;\n        const total = points.length;\n        const halfWidth = this.textureScale > 0 ? this.textureScale * this._width / 2 : this._width / 2;\n\n        for (let i = 0; i < total; i++)\n        {\n            const point = points[i];\n            const index = i * 4;\n\n            if (i < points.length - 1)\n            {\n                nextPoint = points[i + 1];\n            }\n            else\n            {\n                nextPoint = point;\n            }\n\n            perpY = -(nextPoint.x - lastPoint.x);\n            perpX = nextPoint.y - lastPoint.y;\n\n            let ratio = (1 - (i / (total - 1))) * 10;\n\n            if (ratio > 1)\n            {\n                ratio = 1;\n            }\n\n            const perpLength = Math.sqrt((perpX * perpX) + (perpY * perpY));\n\n            if (perpLength < 1e-6)\n            {\n                perpX = 0;\n                perpY = 0;\n            }\n            else\n            {\n                perpX /= perpLength;\n                perpY /= perpLength;\n\n                perpX *= halfWidth;\n                perpY *= halfWidth;\n            }\n\n            vertices[index] = point.x + perpX;\n            vertices[index + 1] = point.y + perpY;\n            vertices[index + 2] = point.x - perpX;\n            vertices[index + 3] = point.y - perpY;\n\n            lastPoint = point;\n        }\n\n        this.buffers[0].update();\n    }\n\n    public update(): void\n    {\n        if (this.textureScale > 0)\n        {\n            this.build(); // we need to update UVs\n        }\n        else\n        {\n            this.updateVertices();\n        }\n    }\n}\n"],"names":[],"mappings":";;AAeO,MAAM,qBAAqB,YAClC,CAAA;AAAA,EAwBI,WAAY,CAAA,KAAA,GAAQ,GAAK,EAAA,MAAA,EAAkB,eAAe,CAC1D,EAAA;AACI,IAAA,KAAA,CAAM,IAAI,YAAa,CAAA,MAAA,CAAO,SAAS,CAAC,CAAA,EACpC,IAAI,YAAa,CAAA,MAAA,CAAO,MAAS,GAAA,CAAC,GAClC,IAAI,WAAA,CAAa,QAAO,MAAS,GAAA,CAAA,IAAK,CAAC,CAAC,CAAA,CAAA;AAE5C,IAAA,IAAA,CAAK,MAAS,GAAA,MAAA,CAAA;AACd,IAAA,IAAA,CAAK,MAAS,GAAA,KAAA,CAAA;AACd,IAAA,IAAA,CAAK,YAAe,GAAA,YAAA,CAAA;AAEpB,IAAA,IAAA,CAAK,KAAM,EAAA,CAAA;AAAA,GACf;AAAA,EAMA,IAAI,KACJ,GAAA;AACI,IAAA,OAAO,IAAK,CAAA,MAAA,CAAA;AAAA,GAChB;AAAA,EAGA,KACA,GAAA;AACI,IAAA,MAAM,SAAS,IAAK,CAAA,MAAA,CAAA;AAEpB,IAAA,IAAI,CAAC,MAAA;AAAQ,MAAA,OAAA;AAEb,IAAM,MAAA,YAAA,GAAe,IAAK,CAAA,SAAA,CAAU,iBAAiB,CAAA,CAAA;AACrD,IAAM,MAAA,QAAA,GAAW,IAAK,CAAA,SAAA,CAAU,eAAe,CAAA,CAAA;AAC/C,IAAM,MAAA,WAAA,GAAc,KAAK,QAAS,EAAA,CAAA;AAGlC,IAAI,IAAA,MAAA,CAAO,SAAS,CACpB,EAAA;AACI,MAAA,OAAA;AAAA,KACJ;AAGA,IAAA,IAAI,YAAa,CAAA,IAAA,CAAK,MAAS,GAAA,CAAA,KAAM,OAAO,MAC5C,EAAA;AACI,MAAA,YAAA,CAAa,IAAO,GAAA,IAAI,YAAa,CAAA,MAAA,CAAO,SAAS,CAAC,CAAA,CAAA;AACtD,MAAA,QAAA,CAAS,IAAO,GAAA,IAAI,YAAa,CAAA,MAAA,CAAO,SAAS,CAAC,CAAA,CAAA;AAClD,MAAA,WAAA,CAAY,OAAO,IAAI,WAAA,CAAa,CAAO,MAAA,CAAA,MAAA,GAAS,KAAK,CAAC,CAAA,CAAA;AAAA,KAC9D;AAEA,IAAA,MAAM,MAAM,QAAS,CAAA,IAAA,CAAA;AACrB,IAAA,MAAM,UAAU,WAAY,CAAA,IAAA,CAAA;AAE5B,IAAA,GAAA,CAAI,CAAK,CAAA,GAAA,CAAA,CAAA;AACT,IAAA,GAAA,CAAI,CAAK,CAAA,GAAA,CAAA,CAAA;AACT,IAAA,GAAA,CAAI,CAAK,CAAA,GAAA,CAAA,CAAA;AACT,IAAA,GAAA,CAAI,CAAK,CAAA,GAAA,CAAA,CAAA;AAET,IAAA,IAAI,MAAS,GAAA,CAAA,CAAA;AACb,IAAA,IAAI,OAAO,MAAO,CAAA,CAAA,CAAA,CAAA;AAClB,IAAM,MAAA,YAAA,GAAe,IAAK,CAAA,MAAA,GAAS,IAAK,CAAA,YAAA,CAAA;AACxC,IAAA,MAAM,QAAQ,MAAO,CAAA,MAAA,CAAA;AAErB,IAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,KAAA,EAAO,CAC3B,EAAA,EAAA;AAEI,MAAA,MAAM,QAAQ,CAAI,GAAA,CAAA,CAAA;AAElB,MAAI,IAAA,IAAA,CAAK,eAAe,CACxB,EAAA;AAEI,QAAA,MAAM,EAAK,GAAA,IAAA,CAAK,CAAI,GAAA,MAAA,CAAO,CAAG,CAAA,CAAA,CAAA,CAAA;AAC9B,QAAA,MAAM,EAAK,GAAA,IAAA,CAAK,CAAI,GAAA,MAAA,CAAO,CAAG,CAAA,CAAA,CAAA,CAAA;AAC9B,QAAA,MAAM,WAAW,IAAK,CAAA,IAAA,CAAM,EAAK,GAAA,EAAA,GAAO,KAAK,EAAG,CAAA,CAAA;AAEhD,QAAA,IAAA,GAAO,MAAO,CAAA,CAAA,CAAA,CAAA;AACd,QAAA,MAAA,IAAU,QAAW,GAAA,YAAA,CAAA;AAAA,OAGzB,MAAA;AAEI,QAAA,MAAA,GAAS,KAAa,KAAA,GAAA,CAAA,CAAA,CAAA;AAAA,OAC1B;AAEA,MAAA,GAAA,CAAI,KAAS,CAAA,GAAA,MAAA,CAAA;AACb,MAAA,GAAA,CAAI,QAAQ,CAAK,CAAA,GAAA,CAAA,CAAA;AAEjB,MAAA,GAAA,CAAI,QAAQ,CAAK,CAAA,GAAA,MAAA,CAAA;AACjB,MAAA,GAAA,CAAI,QAAQ,CAAK,CAAA,GAAA,CAAA,CAAA;AAAA,KACrB;AAEA,IAAA,IAAI,UAAa,GAAA,CAAA,CAAA;AAEjB,IAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,KAAA,GAAQ,GAAG,CAC/B,EAAA,EAAA;AACI,MAAA,MAAM,QAAQ,CAAI,GAAA,CAAA,CAAA;AAElB,MAAA,OAAA,CAAQ,UAAgB,EAAA,CAAA,GAAA,KAAA,CAAA;AACxB,MAAA,OAAA,CAAQ,gBAAgB,KAAQ,GAAA,CAAA,CAAA;AAChC,MAAA,OAAA,CAAQ,gBAAgB,KAAQ,GAAA,CAAA,CAAA;AAEhC,MAAA,OAAA,CAAQ,gBAAgB,KAAQ,GAAA,CAAA,CAAA;AAChC,MAAA,OAAA,CAAQ,gBAAgB,KAAQ,GAAA,CAAA,CAAA;AAChC,MAAA,OAAA,CAAQ,gBAAgB,KAAQ,GAAA,CAAA,CAAA;AAAA,KACpC;AAGA,IAAA,QAAA,CAAS,MAAO,EAAA,CAAA;AAChB,IAAA,WAAA,CAAY,MAAO,EAAA,CAAA;AAEnB,IAAA,IAAA,CAAK,cAAe,EAAA,CAAA;AAAA,GACxB;AAAA,EAGA,cACA,GAAA;AACI,IAAA,MAAM,SAAS,IAAK,CAAA,MAAA,CAAA;AAEpB,IAAI,IAAA,MAAA,CAAO,SAAS,CACpB,EAAA;AACI,MAAA,OAAA;AAAA,KACJ;AAEA,IAAA,IAAI,YAAY,MAAO,CAAA,CAAA,CAAA,CAAA;AACvB,IAAI,IAAA,SAAA,CAAA;AACJ,IAAA,IAAI,KAAQ,GAAA,CAAA,CAAA;AACZ,IAAA,IAAI,KAAQ,GAAA,CAAA,CAAA;AAEZ,IAAM,MAAA,QAAA,GAAW,IAAK,CAAA,OAAA,CAAQ,CAAG,CAAA,CAAA,IAAA,CAAA;AACjC,IAAA,MAAM,QAAQ,MAAO,CAAA,MAAA,CAAA;AACrB,IAAM,MAAA,SAAA,GAAY,IAAK,CAAA,YAAA,GAAe,CAAI,GAAA,IAAA,CAAK,eAAe,IAAK,CAAA,MAAA,GAAS,CAAI,GAAA,IAAA,CAAK,MAAS,GAAA,CAAA,CAAA;AAE9F,IAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,KAAA,EAAO,CAC3B,EAAA,EAAA;AACI,MAAA,MAAM,QAAQ,MAAO,CAAA,CAAA,CAAA,CAAA;AACrB,MAAA,MAAM,QAAQ,CAAI,GAAA,CAAA,CAAA;AAElB,MAAI,IAAA,CAAA,GAAI,MAAO,CAAA,MAAA,GAAS,CACxB,EAAA;AACI,QAAA,SAAA,GAAY,OAAO,CAAI,GAAA,CAAA,CAAA,CAAA;AAAA,OAG3B,MAAA;AACI,QAAY,SAAA,GAAA,KAAA,CAAA;AAAA,OAChB;AAEA,MAAQ,KAAA,GAAA,EAAY,SAAA,CAAA,CAAA,GAAI,SAAU,CAAA,CAAA,CAAA,CAAA;AAClC,MAAQ,KAAA,GAAA,SAAA,CAAU,IAAI,SAAU,CAAA,CAAA,CAAA;AAEhC,MAAA,IAAI,KAAS,GAAA,CAAA,CAAA,GAAK,CAAK,IAAA,KAAA,GAAQ,CAAO,CAAA,IAAA,EAAA,CAAA;AAEtC,MAAA,IAAI,QAAQ,CACZ,EAAA;AACI,QAAQ,KAAA,GAAA,CAAA,CAAA;AAAA,OACZ;AAEA,MAAA,MAAM,aAAa,IAAK,CAAA,IAAA,CAAM,KAAQ,GAAA,KAAA,GAAU,QAAQ,KAAM,CAAA,CAAA;AAE9D,MAAA,IAAI,aAAa,IACjB,EAAA;AACI,QAAQ,KAAA,GAAA,CAAA,CAAA;AACR,QAAQ,KAAA,GAAA,CAAA,CAAA;AAAA,OAGZ,MAAA;AACI,QAAS,KAAA,IAAA,UAAA,CAAA;AACT,QAAS,KAAA,IAAA,UAAA,CAAA;AAET,QAAS,KAAA,IAAA,SAAA,CAAA;AACT,QAAS,KAAA,IAAA,SAAA,CAAA;AAAA,OACb;AAEA,MAAS,QAAA,CAAA,KAAA,CAAA,GAAS,MAAM,CAAI,GAAA,KAAA,CAAA;AAC5B,MAAS,QAAA,CAAA,KAAA,GAAQ,CAAK,CAAA,GAAA,KAAA,CAAM,CAAI,GAAA,KAAA,CAAA;AAChC,MAAS,QAAA,CAAA,KAAA,GAAQ,CAAK,CAAA,GAAA,KAAA,CAAM,CAAI,GAAA,KAAA,CAAA;AAChC,MAAS,QAAA,CAAA,KAAA,GAAQ,CAAK,CAAA,GAAA,KAAA,CAAM,CAAI,GAAA,KAAA,CAAA;AAEhC,MAAY,SAAA,GAAA,KAAA,CAAA;AAAA,KAChB;AAEA,IAAK,IAAA,CAAA,OAAA,CAAQ,GAAG,MAAO,EAAA,CAAA;AAAA,GAC3B;AAAA,EAEA,MACA,GAAA;AACI,IAAI,IAAA,IAAA,CAAK,eAAe,CACxB,EAAA;AACI,MAAA,IAAA,CAAK,KAAM,EAAA,CAAA;AAAA,KAGf,MAAA;AACI,MAAA,IAAA,CAAK,cAAe,EAAA,CAAA;AAAA,KACxB;AAAA,GACJ;AACJ;;;;"}