{"version":3,"file":"MeshPipe.mjs","sources":["../../../../src/scene/mesh/shared/MeshPipe.ts"],"sourcesContent":["import { ExtensionType } from '../../../extensions/Extensions';\nimport { Matrix } from '../../../maths/matrix/Matrix';\nimport { BindGroup } from '../../../rendering/renderers/gpu/shader/BindGroup';\nimport { UniformGroup } from '../../../rendering/renderers/shared/shader/UniformGroup';\nimport { getAdjustedBlendModeBlend } from '../../../rendering/renderers/shared/state/getAdjustedBlendModeBlend';\nimport { color32BitToUniform } from '../../graphics/gpu/colorToUniform';\nimport { type GPUData } from '../../view/ViewContainer';\nimport { BatchableMesh } from './BatchableMesh';\n\nimport type { InstructionSet } from '../../../rendering/renderers/shared/instructions/InstructionSet';\nimport type {\n    InstructionPipe,\n    RenderPipe\n} from '../../../rendering/renderers/shared/instructions/RenderPipe';\nimport type { Renderer } from '../../../rendering/renderers/types';\nimport type { Mesh } from './Mesh';\n\n// TODO Record mode is a P2, will get back to this as it's not a priority\n// const recordMode = true;\n\n/**\n * GPUData for Mesh\n * @internal\n */\nexport class MeshGpuData implements GPUData\n{\n    public meshData?: MeshData;\n    public batchableMesh?: BatchableMesh;\n\n    public destroy()\n    {\n        // BOOM!\n    }\n}\n\n/**\n * The data for the mesh\n * @internal\n */\ninterface MeshData\n{\n    /** if the mesh is batched or not */\n    batched: boolean;\n    /** the size of the index buffer */\n    indexSize: number;\n    /** the size of the vertex buffer */\n    vertexSize: number;\n}\n\n/** @internal */\nexport interface MeshAdaptor\n{\n    init(): void;\n    execute(meshPipe: MeshPipe, mesh: Mesh): void;\n    destroy(): void;\n}\n\n/**\n * The MeshPipe is responsible for handling the rendering of Mesh objects.\n * It manages the batching of meshes, updates their GPU data, and executes the rendering instructions.\n * It also handles the local uniforms for each mesh, such as transformation matrices and colors.\n * @category scene\n * @internal\n */\nexport class MeshPipe implements RenderPipe<Mesh>, InstructionPipe<Mesh>\n{\n    /** @ignore */\n    public static extension = {\n        type: [\n            ExtensionType.WebGLPipes,\n            ExtensionType.WebGPUPipes,\n        ],\n        name: 'mesh',\n    } as const;\n\n    public localUniforms = new UniformGroup({\n        uTransformMatrix: { value: new Matrix(), type: 'mat3x3<f32>' },\n        uColor: { value: new Float32Array([1, 1, 1, 1]), type: 'vec4<f32>' },\n        uRound: { value: 0, type: 'f32' },\n    });\n\n    public localUniformsBindGroup = new BindGroup({\n        0: this.localUniforms,\n    });\n\n    public renderer: Renderer;\n\n    private _adaptor: MeshAdaptor;\n\n    constructor(renderer: Renderer, adaptor: MeshAdaptor)\n    {\n        this.renderer = renderer;\n        this._adaptor = adaptor;\n\n        this._adaptor.init();\n    }\n\n    public validateRenderable(mesh: Mesh): boolean\n    {\n        const meshData = this._getMeshData(mesh);\n\n        const wasBatched = meshData.batched;\n\n        const isBatched = mesh.batched;\n\n        meshData.batched = isBatched;\n\n        if (wasBatched !== isBatched)\n        {\n            return true;\n        }\n        else if (isBatched)\n        {\n            const geometry = mesh._geometry;\n\n            // no need to break the batch if it's the same size\n            if (geometry.indices.length !== meshData.indexSize\n                    || geometry.positions.length !== meshData.vertexSize)\n            {\n                meshData.indexSize = geometry.indices.length;\n                meshData.vertexSize = geometry.positions.length;\n\n                return true;\n            }\n\n            const batchableMesh = this._getBatchableMesh(mesh);\n\n            if (batchableMesh.texture.uid !== mesh._texture.uid)\n            {\n                batchableMesh._textureMatrixUpdateId = -1;\n            }\n\n            return !batchableMesh._batcher.checkAndUpdateTexture(\n                batchableMesh,\n                mesh._texture\n            );\n        }\n\n        return false;\n    }\n\n    public addRenderable(mesh: Mesh, instructionSet: InstructionSet)\n    {\n        const batcher = this.renderer.renderPipes.batch;\n\n        const meshData = this._getMeshData(mesh);\n\n        if (mesh.didViewUpdate)\n        {\n            meshData.indexSize = mesh._geometry.indices?.length;\n            meshData.vertexSize = mesh._geometry.positions?.length;\n        }\n\n        if (meshData.batched)\n        {\n            const gpuBatchableMesh = this._getBatchableMesh(mesh);\n\n            gpuBatchableMesh.setTexture(mesh._texture);\n            gpuBatchableMesh.geometry = mesh._geometry;\n\n            batcher.addToBatch(gpuBatchableMesh, instructionSet);\n        }\n        else\n        {\n            batcher.break(instructionSet);\n\n            instructionSet.add(mesh);\n        }\n    }\n\n    public updateRenderable(mesh: Mesh)\n    {\n        if (mesh.batched)\n        {\n            const gpuBatchableMesh = this._getBatchableMesh(mesh);\n\n            gpuBatchableMesh.setTexture(mesh._texture);\n\n            gpuBatchableMesh.geometry = mesh._geometry;\n\n            gpuBatchableMesh._batcher.updateElement(gpuBatchableMesh);\n        }\n    }\n\n    public execute(mesh: Mesh)\n    {\n        if (!mesh.isRenderable) return;\n\n        mesh.state.blendMode = getAdjustedBlendModeBlend(mesh.groupBlendMode, mesh.texture._source);\n\n        const localUniforms = this.localUniforms;\n\n        localUniforms.uniforms.uTransformMatrix = mesh.groupTransform;\n        localUniforms.uniforms.uRound = this.renderer._roundPixels | mesh._roundPixels;\n        localUniforms.update();\n\n        color32BitToUniform(\n            mesh.groupColorAlpha,\n            localUniforms.uniforms.uColor,\n            0\n        );\n\n        this._adaptor.execute(this, mesh);\n    }\n\n    private _getMeshData(mesh: Mesh): MeshData\n    {\n        mesh._gpuData[this.renderer.uid] ||= new MeshGpuData();\n\n        return mesh._gpuData[this.renderer.uid].meshData || this._initMeshData(mesh);\n    }\n\n    private _initMeshData(mesh: Mesh): MeshData\n    {\n        mesh._gpuData[this.renderer.uid].meshData = {\n            batched: mesh.batched,\n            indexSize: 0,\n            vertexSize: 0,\n        };\n\n        return mesh._gpuData[this.renderer.uid].meshData;\n    }\n\n    private _getBatchableMesh(mesh: Mesh): BatchableMesh\n    {\n        mesh._gpuData[this.renderer.uid] ||= new MeshGpuData();\n\n        return mesh._gpuData[this.renderer.uid].batchableMesh || this._initBatchableMesh(mesh);\n    }\n\n    private _initBatchableMesh(mesh: Mesh): BatchableMesh\n    {\n        // TODO - make this batchable graphics??\n        const gpuMesh: BatchableMesh = new BatchableMesh();\n\n        gpuMesh.renderable = mesh;\n        gpuMesh.setTexture(mesh._texture);\n        gpuMesh.transform = mesh.groupTransform;\n        gpuMesh.roundPixels = (this.renderer._roundPixels | mesh._roundPixels) as 0 | 1;\n\n        mesh._gpuData[this.renderer.uid].batchableMesh = gpuMesh;\n\n        return gpuMesh;\n    }\n\n    public destroy()\n    {\n        this.localUniforms = null;\n        this.localUniformsBindGroup = null;\n\n        this._adaptor.destroy();\n        this._adaptor = null;\n\n        this.renderer = null;\n    }\n}\n"],"names":[],"mappings":"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"}