{"version":3,"file":"getFastGlobalBoundsMixin.mjs","sources":["../../../../src/scene/container/container-mixins/getFastGlobalBoundsMixin.ts"],"sourcesContent":["import { Matrix } from '../../../maths/matrix/Matrix';\nimport { type Renderable } from '../../../rendering/renderers/shared/Renderable';\nimport { type RenderLayer } from '../../layers/RenderLayer';\nimport { Bounds } from '../bounds/Bounds';\nimport { boundsPool } from '../bounds/utils/matrixAndBoundsPool';\n\nimport type { Container } from '../Container';\n\nconst tempMatrix = new Matrix();\n\n/**\n * Interface for the GetFastGlobalBoundsMixin, which provides methods to compute\n * an approximate global bounding box for a container and its children.\n * @category scene\n * @advanced\n */\nexport interface GetFastGlobalBoundsMixin\n{\n    /**\n     * Computes an approximate global bounding box for the container and its children.\n     * This method is optimized for speed by using axis-aligned bounding boxes (AABBs),\n     * and uses the last render results from when it updated the transforms. This function does not update them.\n     * which may result in slightly larger bounds but never smaller than the actual bounds.\n     *\n     * for accurate (but less performant) results use `container.getGlobalBounds`\n     * @param {boolean} [factorRenderLayers] - A flag indicating whether to consider render layers in the calculation.\n     * @param {Bounds} [bounds] - The output bounds object to store the result. If not provided, a new one is created.\n     * @returns {Bounds} The computed bounds.\n     * @advanced\n     */\n    getFastGlobalBounds(factorRenderLayers?: boolean, bounds?: Bounds): Bounds;\n\n    /**\n     * Recursively calculates the global bounds for the container and its children.\n     * This method is used internally by getFastGlobalBounds to traverse the scene graph.\n     * @param {boolean} factorRenderLayers - A flag indicating whether to consider render layers in the calculation.\n     * @param {Bounds} bounds - The bounds object to update with the calculated values.\n     * @param {RenderLayer} currentLayer - The current render layer being processed.\n     * @internal\n     */\n    _getGlobalBoundsRecursive(\n        factorRenderLayers: boolean,\n        bounds: Bounds,\n        currentLayer: RenderLayer,\n    ): void;\n}\n\n/**\n * Mixin providing the implementation of the GetFastGlobalBoundsMixin interface.\n * It includes methods to compute and recursively calculate global bounds for containers.\n * @internal\n */\nexport const getFastGlobalBoundsMixin: Partial<Container> = {\n    getFastGlobalBounds(factorRenderLayers?: boolean, bounds?: Bounds): Bounds\n    {\n        bounds ||= new Bounds();\n\n        // Initialize the bounds for fresh calculations.\n        bounds.clear();\n\n        // Calculate bounds recursively, starting from the current container.\n        this._getGlobalBoundsRecursive(!!factorRenderLayers, bounds, this.parentRenderLayer);\n\n        // Validate the calculated bounds, resetting if invalid.\n        if (!bounds.isValid)\n        {\n            bounds.set(0, 0, 0, 0);\n        }\n\n        // Apply the world transformation to the bounds.\n        const renderGroup = this.renderGroup || this.parentRenderGroup;\n\n        bounds.applyMatrix(renderGroup.worldTransform);\n\n        return bounds;\n    },\n\n    _getGlobalBoundsRecursive(\n        factorRenderLayers: boolean,\n        bounds: Bounds,\n        currentLayer: RenderLayer,\n    )\n    {\n        let localBounds = bounds;\n\n        // Skip if the container is not in the current render layer when factoring render layers.\n        if (factorRenderLayers && this.parentRenderLayer && this.parentRenderLayer !== currentLayer) return;\n\n        // Skip if the container is not fully visible or not measurable.\n        if (this.localDisplayStatus !== 0b111 || (!this.measurable))\n        {\n            return;\n        }\n\n        // Determine if effects need to be managed, requiring separate bounds handling.\n        const manageEffects = !!this.effects.length;\n\n        // Use a temporary bounds object if the container is a render group or has effects.\n        if (this.renderGroup || manageEffects)\n        {\n            localBounds = boundsPool.get().clear();\n        }\n\n        // Add the container's own bounds area to the bounds if it exists.\n        if (this.boundsArea)\n        {\n            bounds.addRect(this.boundsArea, this.worldTransform);\n        }\n        else\n        {\n            // If the container is renderable, add its bounds to the local bounds.\n            if (this.renderPipeId)\n            {\n                const viewBounds = (this as Renderable).bounds;\n\n                localBounds.addFrame(\n                    viewBounds.minX,\n                    viewBounds.minY,\n                    viewBounds.maxX,\n                    viewBounds.maxY,\n                    this.groupTransform\n                );\n            }\n\n            // Recursively process each child to include their bounds.\n            const children = this.children;\n\n            for (let i = 0; i < children.length; i++)\n            {\n                children[i]._getGlobalBoundsRecursive(factorRenderLayers, localBounds, currentLayer);\n            }\n        }\n\n        // If effects are managed, apply them to the bounds.\n        if (manageEffects)\n        {\n            let advanced = false;\n            const renderGroup = this.renderGroup || this.parentRenderGroup;\n\n            // Apply each effect that modifies bounds.\n            for (let i = 0; i < this.effects.length; i++)\n            {\n                if (this.effects[i].addBounds)\n                {\n                    if (!advanced)\n                    {\n                        advanced = true;\n                        localBounds.applyMatrix(renderGroup.worldTransform);\n                    }\n                    this.effects[i].addBounds(localBounds, true);\n                }\n            }\n\n            // Adjust bounds back to the local coordinate space if advanced bounds were calculated.\n            if (advanced)\n            {\n                localBounds.applyMatrix(renderGroup.worldTransform.copyTo(tempMatrix).invert());\n            }\n\n            // Add the local bounds to the final bounds and return the temporary bounds object.\n            bounds.addBounds(localBounds);\n            boundsPool.return(localBounds);\n        }\n        else if (this.renderGroup)\n        {\n            // If the container is a render group, add its local bounds to the final bounds.\n            bounds.addBounds(localBounds, this.relativeGroupTransform);\n            boundsPool.return(localBounds);\n        }\n    }\n\n} as Container;\n"],"names":[],"mappings":"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"}