{"version":3,"file":"RopeGeometry.mjs","sources":["../../../src/scene/mesh-simple/RopeGeometry.ts"],"sourcesContent":["import { MeshGeometry } from '../mesh/shared/MeshGeometry';\n\nimport type { PointData } from '../../maths/point/PointData';\nimport type { MeshGeometryOptions } from '../mesh/shared/MeshGeometry';\n\n/**\n * Constructor options used for `RopeGeometry` instances.\n * ```js\n * const ropeGeometry = new RopeGeometry({\n *    points: [new Point(0, 0), new Point(100, 0)],\n *    width: 10,\n *    textureScale: 0,\n * });\n * ```\n * @see {@link RopeGeometry}\n * @category scene\n * @advanced\n */\nexport interface RopeGeometryOptions\n{\n    /** The width (i.e., thickness) of the rope. */\n    width?: number;\n    /** An array of points that determine the rope. */\n    points?: PointData[];\n    /**\n     * Rope texture scale, if zero then the rope texture is stretched.\n     * 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 '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    textureScale?: number;\n}\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 'pixi.js';\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 * @category scene\n * @advanced\n */\nexport class RopeGeometry extends MeshGeometry\n{\n    /** Default options for RopeGeometry constructor. */\n    public static defaultOptions: RopeGeometryOptions & MeshGeometryOptions = {\n        /** The width (i.e., thickness) of the rope. */\n        width: 200,\n        /** An array of points that determine the rope. */\n        points: [],\n        /** Rope texture scale, if zero then the rope texture is stretched. */\n        textureScale: 0,\n    };\n\n    /** An array of points that determine the rope. */\n    public points: PointData[];\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     * @internal\n     */\n    public _width: number;\n\n    /**\n     * @param options - Options to be applied to rope geometry\n     */\n    constructor(options: RopeGeometryOptions)\n    {\n        const { width, points, textureScale } = { ...RopeGeometry.defaultOptions, ...options };\n\n        super({\n            positions: new Float32Array(points.length * 4),\n            uvs: new Float32Array(points.length * 4),\n            indices: new Uint32Array((points.length - 1) * 6),\n        });\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('aPosition');\n        const uvBuffer = this.getBuffer('aUV');\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    /** Refreshes Rope indices and uvs */\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":"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"}