{"version":3,"file":"PerspectiveMesh.mjs","sources":["../../../src/scene/mesh-perspective/PerspectiveMesh.ts"],"sourcesContent":["import { Texture } from '../../rendering/renderers/shared/texture/Texture';\nimport { definedProps } from '../container/utils/definedProps';\nimport { Mesh } from '../mesh/shared/Mesh';\nimport { PerspectivePlaneGeometry } from './PerspectivePlaneGeometry';\n\nimport type { MeshPlaneOptions } from '../mesh-plane/MeshPlane';\n\n/**\n * Constructor options used for `PerspectiveMesh` instances. Defines the geometry and appearance\n * of a 2D mesh with perspective projection.\n * @example\n * ```ts\n * // Create a perspective mesh with a texture\n * const mesh = new PerspectiveMesh({\n *     texture: Texture.from('myImage.png'),\n *     verticesX: 20,\n *     verticesY: 20,\n *     // Define corners clockwise from top-left\n *     x0: 0,   y0: 0,    // Top-left\n *     x1: 100, y1: 20,   // Top-right (raised)\n *     x2: 100, y2: 100,  // Bottom-right\n *     x3: 0,   y3: 80    // Bottom-left (raised)\n * });\n *\n * // Create a skewed perspective\n * const skewedMesh = new PerspectiveMesh({\n *     texture: Texture.from('background.jpg'),\n *     verticesX: 15,     // More vertices for smoother perspective\n *     verticesY: 15,\n *     x0: 0,   y0: 30,   // Shifted top-left\n *     x1: 128, y1: 0,    // Raised top-right\n *     x2: 128, y2: 128,  // Normal bottom-right\n *     x3: 0,   y3: 98    // Shifted bottom-left\n * });\n * ```\n * @extends MeshPlaneOptions\n * @see {@link PerspectiveMesh} For the mesh implementation\n * @see {@link PerspectivePlaneGeometry} For the underlying geometry\n * @category scene\n * @standard\n * @noInheritDoc\n */\nexport interface PerspectivePlaneOptions extends MeshPlaneOptions\n{\n    /** The x-coordinate of the top-left corner */\n    x0?: number,\n    /** The y-coordinate of the top-left corner */\n    y0?: number,\n    /** The x-coordinate of the top-right corner */\n    x1?: number,\n    /** The y-coordinate of the top-right corner */\n    y1?: number,\n    /** The x-coordinate of the bottom-right corner */\n    x2?: number,\n    /** The y-coordinate of the bottom-right corner */\n    y2?: number,\n    /** The x-coordinate of the bottom-left corner */\n    x3?: number,\n    /** The y-coordinate of the bottom-left corner */\n    y3?: number\n}\n\n/**\n * A perspective mesh that allows you to draw a 2d plane with perspective. Where ever you move the corners\n * the texture will be projected to look like it is in 3d space. Great for mapping a 2D mesh into a 3D scene.\n *\n * The calculations is done at the uv level. This means that the more vertices you have the more smooth\n * the perspective will be. If you have a low amount of vertices you may see the texture stretch. Too many vertices\n * could be slower. It is a balance between performance and quality! We leave that to you to decide.\n *\n * > [!IMPORTANT] This is not a full 3D mesh, it is a 2D mesh with a perspective projection applied to it.\n * @category scene\n * @standard\n * @see {@link PerspectiveMesh}\n * @example\n * ```ts\n * // Create a perspective mesh with a texture\n * const mesh = new PerspectiveMesh({\n *     texture: Texture.from('myImage.png'),\n *     verticesX: 20,\n *     verticesY: 20,\n *     // Define corners clockwise from top-left\n *     x0: 0,   y0: 0,    // Top-left\n *     x1: 100, y1: 20,   // Top-right (raised)\n *     x2: 100, y2: 100,  // Bottom-right\n *     x3: 0,   y3: 80    // Bottom-left (raised)\n * });\n * ```\n */\nexport class PerspectiveMesh extends Mesh<PerspectivePlaneGeometry>\n{\n    /**\n     * Default options for creating a PerspectiveMesh instance.\n     *\n     * Creates a 100x100 pixel square mesh\n     * with a white texture and 10x10 vertex grid for the perspective calculations.\n     * @example\n     * ```ts\n     * // Change defaults globally\n     * PerspectiveMesh.defaultOptions = {\n     *     ...PerspectiveMesh.defaultOptions,\n     *     verticesX: 15,\n     *     verticesY: 15,\n     *     // Move top edge up for default skew\n     *     y0: -20,\n     *     y1: -20\n     * };\n     * ```\n     * @see {@link PerspectivePlaneOptions} For all available options\n     * @see {@link PerspectivePlaneGeometry} For how vertices affect perspective quality\n     */\n    public static defaultOptions: PerspectivePlaneOptions = {\n        texture: Texture.WHITE,\n        verticesX: 10,\n        verticesY: 10,\n        x0: 0,\n        y0: 0,\n        x1: 100,\n        y1: 0,\n        x2: 100,\n        y2: 100,\n        x3: 0,\n        y3: 100\n    };\n\n    /**\n     * @param options - Options to be applied to PerspectiveMesh\n     */\n    constructor(options: PerspectivePlaneOptions)\n    {\n        options = { ...PerspectiveMesh.defaultOptions, ...options };\n\n        const { texture, verticesX, verticesY, ...rest } = options;\n        const planeGeometry = new PerspectivePlaneGeometry(definedProps({\n            width: texture.width,\n            height: texture.height,\n            verticesX,\n            verticesY,\n        }));\n\n        super(definedProps({ ...rest, geometry: planeGeometry }));\n\n        this._texture = texture;\n\n        this.geometry.setCorners(\n            options.x0, options.y0,\n            options.x1, options.y1,\n            options.x2, options.y2,\n            options.x3, options.y3\n        );\n    }\n\n    /** Update the geometry when the texture is updated */\n    protected textureUpdated(): void\n    {\n        const geometry: PerspectivePlaneGeometry = this.geometry as any;\n\n        if (!geometry) return;\n\n        const { width, height } = this.texture;\n\n        if (geometry.width !== width || geometry.height !== height)\n        {\n            geometry.width = width;\n            geometry.height = height;\n            geometry.updateProjection();\n        }\n    }\n\n    set texture(value: Texture)\n    {\n        if (this._texture === value) return;\n\n        super.texture = value;\n\n        this.textureUpdated();\n    }\n\n    /**\n     * The texture that the mesh uses for rendering. When changed, automatically updates\n     * the geometry to match the new texture dimensions.\n     * @example\n     * ```ts\n     * const mesh = new PerspectiveMesh({\n     *     texture: Texture.from('initial.png'),\n     * });\n     *\n     * // Update texture and maintain perspective\n     * mesh.texture = Texture.from('newImage.png');\n     * ```\n     * @see {@link Texture} For texture creation and management\n     * @see {@link PerspectiveMesh#setCorners} For adjusting the mesh perspective\n     */\n    get texture(): Texture\n    {\n        return this._texture;\n    }\n\n    /**\n     * Sets the corners of the mesh to create a perspective transformation. The corners should be\n     * specified in clockwise order starting from the top-left.\n     *\n     * The mesh automatically recalculates the UV coordinates to create the perspective effect.\n     * @example\n     * ```ts\n     * const mesh = new PerspectiveMesh({\n     *     texture: Texture.from('myImage.png'),\n     * });\n     *\n     * // Create a basic perspective tilt\n     * mesh.setCorners(\n     *     0, 0,      // Top-left\n     *     100, 20,   // Top-right (raised)\n     *     100, 100,  // Bottom-right\n     *     0, 80      // Bottom-left\n     * );\n     *\n     * // Create a skewed billboard effect\n     * mesh.setCorners(\n     *     0, 30,     // Top-left (shifted down)\n     *     128, 0,    // Top-right (raised)\n     *     128, 128,  // Bottom-right\n     *     0, 98      // Bottom-left (shifted up)\n     * );\n     *\n     * // Animate perspective\n     * app.ticker.add((delta) => {\n     *     const time = performance.now() / 1000;\n     *     const wave = Math.sin(time) * 20;\n     *\n     *     mesh.setCorners(\n     *         0, wave,      // Top-left\n     *         100, -wave,   // Top-right\n     *         100, 100,     // Bottom-right\n     *         0, 100        // Bottom-left\n     *     );\n     * });\n     * ```\n     * @param x0 - x-coordinate of the top-left corner\n     * @param y0 - y-coordinate of the top-left corner\n     * @param x1 - x-coordinate of the top-right corner\n     * @param y1 - y-coordinate of the top-right corner\n     * @param x2 - x-coordinate of the bottom-right corner\n     * @param y2 - y-coordinate of the bottom-right corner\n     * @param x3 - x-coordinate of the bottom-left corner\n     * @param y3 - y-coordinate of the bottom-left corner\n     * @returns The PerspectiveMesh instance for method chaining\n     * @see {@link PerspectivePlaneGeometry} For the underlying geometry calculations\n     */\n    public setCorners(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number)\n    {\n        this.geometry.setCorners(x0, y0, x1, y1, x2, y2, x3, y3);\n    }\n}\n"],"names":[],"mappings":"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"}