{"version":3,"file":"CubeTextureSource.mjs","sources":["../../../../../../src/rendering/renderers/shared/texture/sources/CubeTextureSource.ts"],"sourcesContent":["import { warn } from '../../../../../utils/logging/warn';\nimport { TextureSource } from './TextureSource';\n\nimport type { TextureSourceOptions } from './TextureSource';\n\n/**\n * The 6 faces of a cube map.\n *\n * Naming matches common engine conventions:\n * - left/right: -X/+X\n * - bottom/top: -Y/+Y\n * - back/front: -Z/+Z\n * @category rendering\n * @advanced\n */\nexport interface CubeTextureFaces<T>\n{\n    left: T;\n    right: T;\n    top: T;\n    bottom: T;\n    front: T;\n    back: T;\n}\n\n/**\n * Options for creating a {@link CubeTextureSource}.\n * @category rendering\n * @advanced\n */\nexport interface CubeTextureSourceOptions extends Omit<\n    TextureSourceOptions<any>,\n    'resource' | 'width' | 'height' | 'dimensions' | 'viewDimension' | 'resolution' | 'format' | 'alphaMode'\n>\n{\n    /**\n     * The 6 face sources that make up the cube texture.\n     *\n     * All faces must match in:\n     * - size (pixelWidth / pixelHeight)\n     * - resolution\n     * - format\n     * - alphaMode\n     */\n    faces: CubeTextureFaces<TextureSource>;\n}\n\n/**\n * A {@link TextureSource} that represents a cube texture (6 faces).\n *\n * Internally, WebGPU uses a 2D texture with 6 array layers and a `cube` view.\n * WebGL uses `TEXTURE_CUBE_MAP`.\n * @example\n * Create a cube source from 6 already-created {@link TextureSource} instances:\n *\n * ```ts\n * const cubeSource = new CubeTextureSource({\n *   faces: { right, left, top, bottom, front, back },\n *   label: 'env-map',\n * });\n * ```\n * @category rendering\n * @advanced\n */\nexport class CubeTextureSource extends TextureSource<CubeTextureFaces<TextureSource>>\n{\n    /** @internal */\n    public override readonly uploadMethodId = 'cube';\n\n    /** The 6 face sources that make up this cube texture. */\n    public readonly faces: CubeTextureFaces<TextureSource>;\n\n    constructor(options: CubeTextureSourceOptions)\n    {\n        const { faces, ...rest } = options;\n\n        // Validate faces are compatible (size/format/alpha/resolution).\n        CubeTextureSource._validateFaces(faces);\n\n        const first = faces.right;\n\n        // Derived settings from the face sources.\n        const derivedResolution = first.resolution;\n        const derivedFormat = first.format;\n        const derivedAlphaMode = first.alphaMode;\n\n        // #if _DEBUG\n        // CubeTextureSourceOptions omits these keys, but warn if someone still passes them at runtime.\n        const ignoredKeys = ([\n            'resolution',\n            'format',\n            'alphaMode',\n            'dimensions',\n            'viewDimension',\n        ] as const).filter((key) => (rest as any)[key] !== undefined);\n\n        if (ignoredKeys.length)\n        {\n            warn(\n                `[CubeTextureSource] Ignoring option(s) [${ignoredKeys.join(', ')}]; these are derived from face sources.`\n            );\n        }\n        // #endif\n\n        super({\n            ...rest,\n            resource: faces,\n            // Keep these aligned with the face sources so any code that reads width/height works.\n            width: first.width,\n            height: first.height,\n            dimensions: '2d',\n            viewDimension: 'cube',\n            arrayLayerCount: 6,\n            resolution: derivedResolution,\n            format: derivedFormat,\n            alphaMode: derivedAlphaMode,\n        });\n\n        this.faces = faces;\n\n        // Forward face updates so the cube gets re-uploaded when any face changes.\n        for (const key of Object.keys(faces) as (keyof CubeTextureFaces<TextureSource>)[])\n        {\n            const face = faces[key];\n\n            face.on('update', this._onFaceUpdate, this);\n            face.on('resize', this._onFaceResize, this);\n            face.on('unload', this._onFaceUpdate, this);\n        }\n    }\n\n    public override destroy(): void\n    {\n        const faces = this.faces;\n\n        if (faces)\n        {\n            for (const key of Object.keys(faces) as (keyof CubeTextureFaces<TextureSource>)[])\n            {\n                const face = faces[key];\n\n                face.off('update', this._onFaceUpdate, this);\n                face.off('resize', this._onFaceResize, this);\n                face.off('unload', this._onFaceUpdate, this);\n            }\n        }\n\n        super.destroy();\n    }\n\n    private _onFaceUpdate()\n    {\n        this.emit('update', this);\n    }\n\n    private _onFaceResize(face: TextureSource)\n    {\n        // Re-validate and resize the cube source to match the face.\n        CubeTextureSource._validateFaces(this.faces);\n\n        this.resize(face.width, face.height, face.resolution);\n    }\n\n    private static _validateFaces(faces: CubeTextureFaces<TextureSource>): void\n    {\n        if (!faces.right || !faces.left || !faces.top || !faces.bottom || !faces.front || !faces.back)\n        {\n            throw new Error('[CubeTextureSource] Requires { left, right, top, bottom, front, back } faces.');\n        }\n\n        const first = faces.right;\n        const expectedPixelWidth = first.pixelWidth;\n        const expectedPixelHeight = first.pixelHeight;\n        const expectedFormat = first.format;\n        const expectedAlphaMode = first.alphaMode;\n        const expectedResolution = first.resolution;\n\n        for (const key of Object.keys(faces) as (keyof CubeTextureFaces<TextureSource>)[])\n        {\n            const face = faces[key];\n\n            if (face.pixelWidth !== expectedPixelWidth || face.pixelHeight !== expectedPixelHeight)\n            {\n                throw new Error(`[CubeTextureSource] Face '${String(key)}' has a different size. All faces must match.`);\n            }\n\n            if (face.format !== expectedFormat)\n            {\n                throw new Error(`[CubeTextureSource] Face '${String(key)}' has a different format. All faces must match.`);\n            }\n\n            if (face.alphaMode !== expectedAlphaMode)\n            {\n                throw new Error(\n                    `[CubeTextureSource] Face '${String(key)}' has a different alphaMode. All faces must match.`\n                );\n            }\n\n            if (face.resolution !== expectedResolution)\n            {\n                throw new Error(\n                    `[CubeTextureSource] Face '${String(key)}' has a different resolution. All faces must match.`\n                );\n            }\n        }\n    }\n}\n\n"],"names":[],"mappings":"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"}