UNPKG

11.4 kBSource Map (JSON)View Raw
1{"version":3,"file":"ScissorSystem.mjs","sources":["../../src/mask/ScissorSystem.ts"],"sourcesContent":["import { extensions, ExtensionType } from '@pixi/extensions';\nimport { Matrix, Rectangle } from '@pixi/math';\nimport { settings } from '@pixi/settings';\nimport { AbstractMaskSystem } from './AbstractMaskSystem';\n\nimport type { ExtensionMetadata } from '@pixi/extensions';\nimport type { Renderer } from '../Renderer';\nimport type { MaskData } from './MaskData';\n\nconst tempMatrix = new Matrix();\nconst rectPool: Rectangle[] = [];\n\n/**\n * System plugin to the renderer to manage scissor masking.\n *\n * Scissor masking discards pixels outside of a rectangle called the scissor box. The scissor box is in the framebuffer\n * viewport's space; however, the mask's rectangle is projected from world-space to viewport space automatically\n * by this system.\n * @memberof PIXI\n */\nexport class ScissorSystem extends AbstractMaskSystem\n{\n /** @ignore */\n static extension: ExtensionMetadata = {\n type: ExtensionType.RendererSystem,\n name: 'scissor',\n };\n\n /**\n * @param {PIXI.Renderer} renderer - The renderer this System works for.\n */\n constructor(renderer: Renderer)\n {\n super(renderer);\n\n this.glConst = settings.ADAPTER.getWebGLRenderingContext().SCISSOR_TEST;\n }\n\n getStackLength(): number\n {\n const maskData = this.maskStack[this.maskStack.length - 1];\n\n if (maskData)\n {\n return maskData._scissorCounter;\n }\n\n return 0;\n }\n\n /**\n * evaluates _boundsTransformed, _scissorRect for MaskData\n * @param maskData\n */\n calcScissorRect(maskData: MaskData): void\n {\n if (maskData._scissorRectLocal)\n {\n return;\n }\n\n const prevData = maskData._scissorRect;\n const { maskObject } = maskData;\n const { renderer } = this;\n const renderTextureSystem = renderer.renderTexture;\n const rect = maskObject.getBounds(true, rectPool.pop() ?? new Rectangle());\n\n this.roundFrameToPixels(rect,\n renderTextureSystem.current ? renderTextureSystem.current.resolution : renderer.resolution,\n renderTextureSystem.sourceFrame,\n renderTextureSystem.destinationFrame,\n renderer.projection.transform);\n\n if (prevData)\n {\n rect.fit(prevData);\n }\n maskData._scissorRectLocal = rect;\n }\n\n private static isMatrixRotated(matrix: Matrix)\n {\n if (!matrix)\n {\n return false;\n }\n const { a, b, c, d } = matrix;\n\n // Skip if skew/rotation present in matrix, except for multiple of 90° rotation. If rotation\n // is a multiple of 90°, then either pair of (b,c) or (a,d) will be (0,0).\n return ((Math.abs(b) > 1e-4 || Math.abs(c) > 1e-4)\n && (Math.abs(a) > 1e-4 || Math.abs(d) > 1e-4));\n }\n\n /**\n * Test, whether the object can be scissor mask with current renderer projection.\n * Calls \"calcScissorRect()\" if its true.\n * @param maskData - mask data\n * @returns whether Whether the object can be scissor mask\n */\n public testScissor(maskData: MaskData): boolean\n {\n const { maskObject } = maskData;\n\n if (!maskObject.isFastRect || !maskObject.isFastRect())\n {\n return false;\n }\n if (ScissorSystem.isMatrixRotated(maskObject.worldTransform))\n {\n return false;\n }\n if (ScissorSystem.isMatrixRotated(this.renderer.projection.transform))\n {\n return false;\n }\n\n this.calcScissorRect(maskData);\n\n const rect = maskData._scissorRectLocal;\n\n return rect.width > 0 && rect.height > 0;\n }\n\n private roundFrameToPixels(\n frame: Rectangle,\n resolution: number,\n bindingSourceFrame: Rectangle,\n bindingDestinationFrame: Rectangle,\n transform?: Matrix,\n )\n {\n if (ScissorSystem.isMatrixRotated(transform))\n {\n return;\n }\n\n transform = transform ? tempMatrix.copyFrom(transform) : tempMatrix.identity();\n\n // Get forward transform from world space to screen space\n transform\n .translate(-bindingSourceFrame.x, -bindingSourceFrame.y)\n .scale(\n bindingDestinationFrame.width / bindingSourceFrame.width,\n bindingDestinationFrame.height / bindingSourceFrame.height)\n .translate(bindingDestinationFrame.x, bindingDestinationFrame.y);\n\n // Convert frame to screen space\n (this.renderer.filter as any).transformAABB(transform, frame);\n\n frame.fit(bindingDestinationFrame);\n frame.x = Math.round(frame.x * resolution);\n frame.y = Math.round(frame.y * resolution);\n frame.width = Math.round(frame.width * resolution);\n frame.height = Math.round(frame.height * resolution);\n }\n\n /**\n * Applies the Mask and adds it to the current stencil stack.\n * @author alvin\n * @param maskData - The mask data.\n */\n push(maskData: MaskData): void\n {\n if (!maskData._scissorRectLocal)\n {\n this.calcScissorRect(maskData);\n }\n\n const { gl } = this.renderer;\n\n if (!maskData._scissorRect)\n {\n gl.enable(gl.SCISSOR_TEST);\n }\n\n maskData._scissorCounter++;\n maskData._scissorRect = maskData._scissorRectLocal;\n this._useCurrent();\n }\n\n /**\n * This should be called after a mask is popped off the mask stack. It will rebind the scissor box to be latest with the\n * last mask in the stack.\n *\n * This can also be called when you directly modify the scissor box and want to restore PixiJS state.\n * @param maskData - The mask data.\n */\n pop(maskData?: MaskData): void\n {\n const { gl } = this.renderer;\n\n if (maskData)\n {\n rectPool.push(maskData._scissorRectLocal);\n }\n\n if (this.getStackLength() > 0)\n {\n this._useCurrent();\n }\n else\n {\n gl.disable(gl.SCISSOR_TEST);\n }\n }\n\n /**\n * Setup renderer to use the current scissor data.\n * @private\n */\n _useCurrent(): void\n {\n const rect = this.maskStack[this.maskStack.length - 1]._scissorRect;\n let y: number;\n\n if (this.renderer.renderTexture.current)\n {\n y = rect.y;\n }\n else\n {\n // flipY. In future we'll have it over renderTextures as an option\n y = this.renderer.height - rect.height - rect.y;\n }\n\n this.renderer.gl.scissor(rect.x, y, rect.width, rect.height);\n }\n}\n\nextensions.add(ScissorSystem);\n"],"names":[],"mappings":"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"}
\No newline at end of file