{"version":3,"file":"Culler.mjs","sources":["../../src/culling/Culler.ts"],"sourcesContent":["import { Matrix } from '../maths/matrix/Matrix';\nimport { Rectangle } from '../maths/shapes/Rectangle';\nimport { Bounds } from '../scene/container/bounds/Bounds';\nimport { getGlobalBounds } from '../scene/container/bounds/getGlobalBounds';\n\nimport type { Container } from '../scene/container/Container';\n\nconst tempBounds = new Bounds();\nconst tempMatrix = new Matrix();\nconst tempRectangle = new Rectangle();\n\n/**\n * A rectangle-like object that contains x, y, width, and height properties.\n * @example\n * const rect = { x: 0, y: 0, width: 100, height: 100 };\n * @category utils\n * @advanced\n */\nexport type RectangleLike = {x: number, y: number, width: number, height: number};\n\n/**\n * The Culler class is responsible for managing and culling containers.\n * Culling optimizes rendering performance by skipping objects outside the visible area.\n *\n * > [!IMPORTANT] culling is not always a golden bullet, it can be more expensive than rendering\n * > objects that are not visible, so it is best used in scenarios where you have many objects\n * > that are not visible at the same time, such as in large scenes or games with many sprites.\n * @example\n * ```ts\n * import { Culler, Container, Rectangle } from 'pixi.js';\n *\n * // Create a culler and container\n * const culler = new Culler();\n * const stage = new Container();\n *\n * // Set up container with culling\n * stage.cullable = true;\n * stage.cullArea = new Rectangle(0, 0, 800, 600);\n *\n * // Add some sprites that will be culled\n * for (let i = 0; i < 1000; i++) {\n *     const sprite = Sprite.from('texture.png');\n *     sprite.x = Math.random() * 2000;\n *     sprite.y = Math.random() * 2000;\n *     sprite.cullable = true;\n *     stage.addChild(sprite);\n * }\n *\n * // Cull objects outside view\n * culler.cull(stage, {\n *     x: 0,\n *     y: 0,\n *     width: 800,\n *     height: 600\n * });\n *\n * // Only visible objects will be rendered\n * renderer.render(stage);\n * ```\n * @see {@link CullerPlugin} For automatic culling in applications\n * @see {@link CullingMixinConstructor} For culling properties\n * @category scene\n * @standard\n */\nexport class Culler\n{\n    /**\n     * Culls the children of a specific container based on the given view rectangle.\n     * This determines which objects should be rendered and which can be skipped.\n     * @param container - The container to cull. Must be a Container instance.\n     * @param view - The view rectangle that defines the visible area\n     * @param skipUpdateTransform - Whether to skip updating transforms for better performance\n     * @example\n     * ```ts\n     * // Basic culling with view bounds\n     * const culler = new Culler();\n     * culler.cull(stage, {\n     *     x: 0,\n     *     y: 0,\n     *     width: 800,\n     *     height: 600\n     * });\n     *\n     * // Culling to renderer screen\n     * culler.cull(stage, renderer.screen, false);\n     * ```\n     * @remarks\n     * - Recursively processes all cullable children\n     * - Uses cullArea if defined, otherwise calculates bounds\n     * - Performance depends on scene complexity\n     * @see {@link CullingMixinConstructor.cullable} For enabling culling on objects\n     * @see {@link CullingMixinConstructor.cullArea} For custom culling boundaries\n     */\n    public cull(container: Container, view: RectangleLike, skipUpdateTransform = true)\n    {\n        this._cullRecursive(container, view, skipUpdateTransform);\n    }\n\n    private _cullRecursive(container: Container, view: RectangleLike, skipUpdateTransform = true)\n    {\n        if (container.cullable && container.measurable && container.includeInBuild)\n        {\n            if (container.cullArea)\n            {\n                tempRectangle.x = view.x;\n                tempRectangle.y = view.y;\n                tempRectangle.width = view.width;\n                tempRectangle.height = view.height;\n\n                const transform = skipUpdateTransform\n                    ? container.worldTransform\n                    : container.getGlobalTransform(tempMatrix, skipUpdateTransform);\n\n                container.culled = !tempRectangle.intersects(\n                    container.cullArea,\n                    transform\n                );\n            }\n            else\n            {\n                const bounds = getGlobalBounds(container, skipUpdateTransform, tempBounds);\n\n                // check view intersection..\n                container.culled = bounds.x >= view.x + view.width\n                    || bounds.y >= view.y + view.height\n                    || bounds.x + bounds.width <= view.x\n                    || bounds.y + bounds.height <= view.y;\n            }\n        }\n        else\n        {\n            container.culled = false;\n        }\n\n        // dont process children if not needed\n        if (\n            !container.cullableChildren\n            || container.culled\n            || !container.renderable\n            || !container.measurable\n            || !container.includeInBuild\n        ) return;\n\n        for (let i = 0; i < container.children.length; i++)\n        {\n            this._cullRecursive(container.children[i], view, skipUpdateTransform);\n        }\n    }\n\n    /**\n     * A shared instance of the Culler class. Provides a global culler instance for convenience.\n     * @example\n     * ```ts\n     * // Use the shared instance instead of creating a new one\n     * Culler.shared.cull(stage, {\n     *     x: 0,\n     *     y: 0,\n     *     width: 800,\n     *     height: 600\n     * });\n     * ```\n     * @see {@link CullerPlugin} For automatic culling using this instance\n     */\n    public static shared = new Culler();\n}\n"],"names":[],"mappings":";;;;;;AAOA,MAAM,UAAA,GAAa,IAAI,MAAA,EAAO;AAC9B,MAAM,UAAA,GAAa,IAAI,MAAA,EAAO;AAC9B,MAAM,aAAA,GAAgB,IAAI,SAAA,EAAU;AAuD7B,MAAM,OAAA,GAAN,MAAM,OAAA,CACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4BW,IAAA,CAAK,SAAA,EAAsB,IAAA,EAAqB,mBAAA,GAAsB,IAAA,EAC7E;AACI,IAAA,IAAA,CAAK,cAAA,CAAe,SAAA,EAAW,IAAA,EAAM,mBAAmB,CAAA;AAAA,EAC5D;AAAA,EAEQ,cAAA,CAAe,SAAA,EAAsB,IAAA,EAAqB,mBAAA,GAAsB,IAAA,EACxF;AACI,IAAA,IAAI,SAAA,CAAU,QAAA,IAAY,SAAA,CAAU,UAAA,IAAc,UAAU,cAAA,EAC5D;AACI,MAAA,IAAI,UAAU,QAAA,EACd;AACI,QAAA,aAAA,CAAc,IAAI,IAAA,CAAK,CAAA;AACvB,QAAA,aAAA,CAAc,IAAI,IAAA,CAAK,CAAA;AACvB,QAAA,aAAA,CAAc,QAAQ,IAAA,CAAK,KAAA;AAC3B,QAAA,aAAA,CAAc,SAAS,IAAA,CAAK,MAAA;AAE5B,QAAA,MAAM,YAAY,mBAAA,GACZ,SAAA,CAAU,iBACV,SAAA,CAAU,kBAAA,CAAmB,YAAY,mBAAmB,CAAA;AAElE,QAAA,SAAA,CAAU,MAAA,GAAS,CAAC,aAAA,CAAc,UAAA;AAAA,UAC9B,SAAA,CAAU,QAAA;AAAA,UACV;AAAA,SACJ;AAAA,MACJ,CAAA,MAEA;AACI,QAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,SAAA,EAAW,mBAAA,EAAqB,UAAU,CAAA;AAGzE,QAAA,SAAA,CAAU,MAAA,GAAS,OAAO,CAAA,IAAK,IAAA,CAAK,IAAI,IAAA,CAAK,KAAA,IACtC,MAAA,CAAO,CAAA,IAAK,IAAA,CAAK,CAAA,GAAI,KAAK,MAAA,IAC1B,MAAA,CAAO,CAAA,GAAI,MAAA,CAAO,KAAA,IAAS,IAAA,CAAK,KAChC,MAAA,CAAO,CAAA,GAAI,MAAA,CAAO,MAAA,IAAU,IAAA,CAAK,CAAA;AAAA,MAC5C;AAAA,IACJ,CAAA,MAEA;AACI,MAAA,SAAA,CAAU,MAAA,GAAS,KAAA;AAAA,IACvB;AAGA,IAAA,IACI,CAAC,SAAA,CAAU,gBAAA,IACR,SAAA,CAAU,MAAA,IACV,CAAC,SAAA,CAAU,UAAA,IACX,CAAC,SAAA,CAAU,UAAA,IACX,CAAC,UAAU,cAAA,EAChB;AAEF,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,SAAA,CAAU,QAAA,CAAS,QAAQ,CAAA,EAAA,EAC/C;AACI,MAAA,IAAA,CAAK,eAAe,SAAA,CAAU,QAAA,CAAS,CAAC,CAAA,EAAG,MAAM,mBAAmB,CAAA;AAAA,IACxE;AAAA,EACJ;AAiBJ,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AApGa,OAAA,CAmGK,MAAA,GAAS,IAAI,OAAA,EAAO;AAnG/B,IAAM,MAAA,GAAN;;;;"}