{"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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"}