gdcore-tools 2.0.0-gd-v5.5.224-autobuild → 2.0.0-gd-v5.5.226-autobuild
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Runtime/CustomRuntimeObject.js +1 -1
- package/dist/Runtime/CustomRuntimeObject.js.map +2 -2
- package/dist/Runtime/CustomRuntimeObject2D.js.map +2 -2
- package/dist/Runtime/Extensions/3D/A_RuntimeObject3D.js.map +2 -2
- package/dist/Runtime/Extensions/3D/Base3DBehavior.js.map +2 -2
- package/dist/Runtime/Extensions/3D/Cube3DRuntimeObject.js +1 -1
- package/dist/Runtime/Extensions/3D/Cube3DRuntimeObject.js.map +2 -2
- package/dist/Runtime/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.js +1 -1
- package/dist/Runtime/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.js.map +2 -2
- package/dist/Runtime/Extensions/3D/CustomRuntimeObject3D.js.map +2 -2
- package/dist/Runtime/Extensions/3D/CustomRuntimeObject3DRenderer.js +1 -1
- package/dist/Runtime/Extensions/3D/CustomRuntimeObject3DRenderer.js.map +2 -2
- package/dist/Runtime/Extensions/3D/JsExtension.js +219 -108
- package/dist/Runtime/Extensions/3D/Model3DRuntimeObject.js +1 -1
- package/dist/Runtime/Extensions/3D/Model3DRuntimeObject.js.map +2 -2
- package/dist/Runtime/Extensions/3D/Model3DRuntimeObject3DRenderer.js +1 -1
- package/dist/Runtime/Extensions/3D/Model3DRuntimeObject3DRenderer.js.map +2 -2
- package/dist/Runtime/Extensions/AdMob/JsExtension.js +63 -1
- package/dist/Runtime/Extensions/AdMob/admobtools.js +1 -1
- package/dist/Runtime/Extensions/AdMob/admobtools.js.map +2 -2
- package/dist/Runtime/Extensions/AdvancedWindow/electron-advancedwindowtools.js.map +2 -2
- package/dist/Runtime/Extensions/AnchorBehavior/anchorruntimebehavior.js +1 -1
- package/dist/Runtime/Extensions/AnchorBehavior/anchorruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/BBText/JsExtension.js +10 -9
- package/dist/Runtime/Extensions/BBText/bbtextruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/BitmapText/JsExtension.js +4 -6
- package/dist/Runtime/Extensions/BitmapText/bitmaptextruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/Extensions/BitmapText/bitmaptextruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/DialogueTree/dialoguetools.js.map +2 -2
- package/dist/Runtime/Extensions/DraggableBehavior/draggableruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/adjustment-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/advanced-bloom-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/ascii-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/bevel-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/black-and-white-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/blending-mode-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/brightness-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/bulge-pinch-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/color-map-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/color-replace-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/crt-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/displacement-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/dot-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/drop-shadow-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/glitch-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/glow-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/godray-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/kawase-blur-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/noise-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/old-film-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/outline-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/pixelate-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/pixi-filters/types/drop-shadow/types.d.ts +10 -4
- package/dist/Runtime/Extensions/Effects/radial-blur-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/reflection-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/rgb-split-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/sepia-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/shockwave-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/tilt-shift-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/twist-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/Effects/zoom-blur-pixi-filter.js.map +2 -2
- package/dist/Runtime/Extensions/ExampleJsExtension/dummyeffect.js.map +2 -2
- package/dist/Runtime/Extensions/FacebookInstantGames/facebookinstantgamestools.js.map +2 -2
- package/dist/Runtime/Extensions/Firebase/A_firebasejs/firebase.d.ts +5 -4
- package/dist/Runtime/Extensions/Firebase/B_firebasetools/D_cloudfirestoretools.js.map +2 -2
- package/dist/Runtime/Extensions/Firebase/B_firebasetools/D_remoteconfigtools.js.map +2 -2
- package/dist/Runtime/Extensions/Firebase/JsExtension.js +21 -21
- package/dist/Runtime/Extensions/JsExtensionTypes.d.ts +1 -0
- package/dist/Runtime/Extensions/Leaderboards/leaderboardstools.js.map +2 -2
- package/dist/Runtime/Extensions/Lighting/JsExtension.js +2 -2
- package/dist/Runtime/Extensions/Lighting/lightobstacleruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/Lighting/lightruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/Extensions/Lighting/lightruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/LinkedObjects/linkedobjects.js.map +2 -2
- package/dist/Runtime/Extensions/Multiplayer/JsExtension.js +122 -0
- package/dist/Runtime/Extensions/Multiplayer/messageManager.js.map +2 -2
- package/dist/Runtime/Extensions/Multiplayer/multiplayerVariablesManager.js.map +2 -2
- package/dist/Runtime/Extensions/Multiplayer/multiplayercomponents.js +1 -1
- package/dist/Runtime/Extensions/Multiplayer/multiplayercomponents.js.map +2 -2
- package/dist/Runtime/Extensions/Multiplayer/multiplayerobjectruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/Multiplayer/multiplayertools.js +1 -1
- package/dist/Runtime/Extensions/Multiplayer/multiplayertools.js.map +2 -2
- package/dist/Runtime/Extensions/Multiplayer/peerJsHelper.js +1 -1
- package/dist/Runtime/Extensions/Multiplayer/peerJsHelper.js.map +2 -2
- package/dist/Runtime/Extensions/Multiplayer/peerjs.d.ts +8 -10
- package/dist/Runtime/Extensions/P2P/peerjs.d.ts +8 -10
- package/dist/Runtime/Extensions/PanelSpriteObject/panelspriteruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/Extensions/PanelSpriteObject/panelspriteruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/ParticleSystem/particleemitterobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/Extensions/ParticleSystem/particleemitterobject.js.map +2 -2
- package/dist/Runtime/Extensions/ParticleSystem/pixi-particles-pixi-renderer.d.ts +2 -1
- package/dist/Runtime/Extensions/PathfindingBehavior/pathfindingobstacleruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/PathfindingBehavior/pathfindingruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/Physics2Behavior/JsExtension.js +106 -106
- package/dist/Runtime/Extensions/Physics2Behavior/box2d.d.ts +13 -7
- package/dist/Runtime/Extensions/Physics2Behavior/physics2runtimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/Physics3DBehavior/Physics3DRuntimeBehavior.js.map +2 -2
- package/dist/Runtime/Extensions/Physics3DBehavior/PhysicsCharacter3DRuntimeBehavior.js +1 -1
- package/dist/Runtime/Extensions/Physics3DBehavior/PhysicsCharacter3DRuntimeBehavior.js.map +2 -2
- package/dist/Runtime/Extensions/PhysicsBehavior/physicsruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/PlatformBehavior/platformerobjectruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/PlatformBehavior/platformruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/PlayerAuthentication/playerauthenticationcomponents.js.map +1 -1
- package/dist/Runtime/Extensions/PlayerAuthentication/playerauthenticationtools.js +1 -1
- package/dist/Runtime/Extensions/PlayerAuthentication/playerauthenticationtools.js.map +2 -2
- package/dist/Runtime/Extensions/PrimitiveDrawing/shapepainterruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/Extensions/PrimitiveDrawing/shapepainterruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/SpatialSound/spatialsoundtools.js +1 -1
- package/dist/Runtime/Extensions/SpatialSound/spatialsoundtools.js.map +2 -2
- package/dist/Runtime/Extensions/Spine/JsExtension.js +5 -4
- package/dist/Runtime/Extensions/Spine/managers/pixi-spine-atlas-manager.js +1 -1
- package/dist/Runtime/Extensions/Spine/managers/pixi-spine-atlas-manager.js.map +2 -2
- package/dist/Runtime/Extensions/Spine/managers/pixi-spine-manager.js +1 -1
- package/dist/Runtime/Extensions/Spine/managers/pixi-spine-manager.js.map +2 -2
- package/dist/Runtime/Extensions/Spine/spineruntimeobject-pixi-renderer.js +1 -1
- package/dist/Runtime/Extensions/Spine/spineruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/Extensions/Spine/spineruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/Steamworks/JsExtension.js +12 -12
- package/dist/Runtime/Extensions/Steamworks/Z_steamworksinputtools.js.map +2 -2
- package/dist/Runtime/Extensions/Steamworks/steamworkstools.js.map +2 -2
- package/dist/Runtime/Extensions/TextEntryObject/textentryruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/Extensions/TextInput/textinputruntimeobject-pixi-renderer.js +1 -1
- package/dist/Runtime/Extensions/TextInput/textinputruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/Extensions/TextInput/textinputruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/TextObject/textruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/Extensions/TextObject/textruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/TileMap/JsExtension.js +20 -18
- package/dist/Runtime/Extensions/TileMap/TileMapRuntimeManager.js.map +2 -2
- package/dist/Runtime/Extensions/TileMap/collision/TransformedTileMap.js.map +2 -2
- package/dist/Runtime/Extensions/TileMap/helper/dts/model/TileMapModel.d.ts +1 -3
- package/dist/Runtime/Extensions/TileMap/simpletilemapruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/TileMap/tilemapcollisionmaskruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject-pixi-renderer.js.map +1 -1
- package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/TiledSpriteObject/tiledspriteruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/Extensions/TiledSpriteObject/tiledspriteruntimeobject.js.map +2 -2
- package/dist/Runtime/Extensions/TopDownMovementBehavior/topdownmovementruntimebehavior.js.map +2 -2
- package/dist/Runtime/Extensions/TweenBehavior/tweenruntimebehavior.js.map +1 -1
- package/dist/Runtime/Extensions/Video/JsExtension.js +2 -1
- package/dist/Runtime/Extensions/Video/videoruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/Extensions/Video/videoruntimeobject.js.map +2 -2
- package/dist/Runtime/InAppTutorialMessage.js +6 -0
- package/dist/Runtime/InAppTutorialMessage.js.map +7 -0
- package/dist/Runtime/Model3DManager.js.map +2 -2
- package/dist/Runtime/ResourceLoader.js.map +2 -2
- package/dist/Runtime/RuntimeCustomObjectLayer.js +1 -1
- package/dist/Runtime/RuntimeCustomObjectLayer.js.map +2 -2
- package/dist/Runtime/RuntimeInstanceContainer.js.map +1 -1
- package/dist/Runtime/RuntimeLayer.js.map +2 -2
- package/dist/Runtime/SpriteAnimator.js.map +2 -2
- package/dist/Runtime/affinetransformation.js.map +1 -1
- package/dist/Runtime/debugger-client/abstract-debugger-client.js.map +2 -2
- package/dist/Runtime/debugger-client/hot-reloader.js +2 -2
- package/dist/Runtime/debugger-client/hot-reloader.js.map +2 -2
- package/dist/Runtime/debugger-client/websocket-debugger-client.js +1 -1
- package/dist/Runtime/debugger-client/websocket-debugger-client.js.map +2 -2
- package/dist/Runtime/events-tools/networktools.js +1 -1
- package/dist/Runtime/events-tools/networktools.js.map +2 -2
- package/dist/Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.js.map +2 -2
- package/dist/Runtime/gd.js.map +2 -2
- package/dist/Runtime/howler-sound-manager/howler-sound-manager.js +1 -1
- package/dist/Runtime/howler-sound-manager/howler-sound-manager.js.map +2 -2
- package/dist/Runtime/inputmanager.js.map +2 -2
- package/dist/Runtime/jsonmanager.js.map +2 -2
- package/dist/Runtime/layer.js.map +2 -2
- package/dist/Runtime/libs/nanomarkdown.js +5 -0
- package/dist/Runtime/libs/nanomarkdown.js.map +7 -0
- package/dist/Runtime/object-capabilities/AnimatableBehavior.js.map +2 -2
- package/dist/Runtime/object-capabilities/EffectBehavior.js.map +2 -2
- package/dist/Runtime/object-capabilities/FlippableBehavior.js.map +2 -2
- package/dist/Runtime/object-capabilities/OpacityBehavior.js.map +2 -2
- package/dist/Runtime/object-capabilities/ResizableBehavior.js.map +2 -2
- package/dist/Runtime/object-capabilities/ScalableBehavior.js.map +2 -2
- package/dist/Runtime/object-capabilities/TextContainerBehavior.js.map +2 -2
- package/dist/Runtime/pixi-renderers/CustomRuntimeObject2DPixiRenderer.js.map +2 -2
- package/dist/Runtime/pixi-renderers/DebuggerPixiRenderer.js.map +2 -2
- package/dist/Runtime/pixi-renderers/layer-pixi-renderer.js.map +2 -2
- package/dist/Runtime/pixi-renderers/loadingscreen-pixi-renderer.js.map +2 -2
- package/dist/Runtime/pixi-renderers/pixi-bitmapfont-manager.js.map +2 -2
- package/dist/Runtime/pixi-renderers/pixi-filters-tools.js.map +2 -2
- package/dist/Runtime/pixi-renderers/pixi-image-manager.js +1 -1
- package/dist/Runtime/pixi-renderers/pixi-image-manager.js.map +2 -2
- package/dist/Runtime/pixi-renderers/pixi.js +123 -177
- package/dist/Runtime/pixi-renderers/runtimegame-pixi-renderer.js +1 -1
- package/dist/Runtime/pixi-renderers/runtimegame-pixi-renderer.js.map +2 -2
- package/dist/Runtime/pixi-renderers/runtimescene-pixi-renderer.js.map +2 -2
- package/dist/Runtime/pixi-renderers/spriteruntimeobject-pixi-renderer.js.map +2 -2
- package/dist/Runtime/profiler.js.map +2 -2
- package/dist/Runtime/runtimegame.js +1 -1
- package/dist/Runtime/runtimegame.js.map +2 -2
- package/dist/Runtime/runtimeobject.js +1 -1
- package/dist/Runtime/runtimeobject.js.map +2 -2
- package/dist/Runtime/runtimescene.js.map +2 -2
- package/dist/Runtime/runtimewatermark.js.map +2 -2
- package/dist/Runtime/scenestack.js.map +2 -2
- package/dist/Runtime/spriteruntimeobject.js.map +2 -2
- package/dist/Runtime/variable.js.map +2 -2
- package/dist/Runtime/variablescontainer.js.map +2 -2
- package/dist/lib/libGD.cjs +1 -1
- package/dist/lib/libGD.wasm +0 -0
- package/gd.d.ts +5 -2
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../GDevelop/GDJS/Runtime/pixi-renderers/layer-pixi-renderer.ts"],
|
|
4
|
-
"sourcesContent": ["/*\n * GDevelop JS Platform\n * Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.\n * This project is released under the MIT License.\n */\n\nnamespace gdjs {\n const logger = new gdjs.Logger('LayerPixiRenderer');\n\n /**\n * The renderer for a gdjs.Layer using Pixi.js.\n */\n export class LayerPixiRenderer {\n private _pixiContainer: PIXI.Container;\n\n private _layer: gdjs.RuntimeLayer;\n\n /** For a lighting layer, the sprite used to display the render texture. */\n private _lightingSprite: PIXI.Sprite | null = null;\n private _isLightingLayer: boolean;\n private _clearColor: Array<integer>;\n\n /**\n * The render texture where the whole 2D layer is rendered.\n * The render texture is then used for lighting (if it's a light layer)\n * or to be rendered in a 3D scene (for a 2D+3D layer).\n */\n private _renderTexture: PIXI.RenderTexture | null = null;\n\n // Width and height are tracked when a render texture is used.\n private _oldWidth: float | null = null;\n private _oldHeight: float | null = null;\n\n // For a 3D (or 2D+3D) layer:\n private _threeGroup: THREE.Group | null = null;\n private _threeScene: THREE.Scene | null = null;\n private _threeCamera:\n | THREE.PerspectiveCamera\n | THREE.OrthographicCamera\n | null = null;\n private _threeCameraDirty: boolean = false;\n private _threeEffectComposer: THREE_ADDONS.EffectComposer | null = null;\n\n // For a 2D+3D layer, the 2D rendering is done on the render texture\n // and then must be displayed on a plane in the 3D world:\n private _threePlaneTexture: THREE.Texture | null = null;\n private _threePlaneGeometry: THREE.PlaneGeometry | null = null;\n private _threePlaneMaterial: THREE.ShaderMaterial | null = null;\n private _threePlaneMesh: THREE.Mesh | null = null;\n\n /**\n * Pixi doesn't sort children with zIndex == 0.\n */\n private static readonly zeroZOrderForPixi = Math.pow(2, -24);\n\n private static vectorForProjections: THREE.Vector3 | null = null;\n\n /**\n * @param layer The layer\n * @param runtimeInstanceContainerRenderer The scene renderer\n */\n constructor(\n layer: gdjs.RuntimeLayer,\n runtimeInstanceContainerRenderer: gdjs.RuntimeInstanceContainerRenderer,\n runtimeGameRenderer: gdjs.RuntimeGameRenderer\n ) {\n this._pixiContainer = new PIXI.Container();\n this._pixiContainer.sortableChildren = true;\n this._layer = layer;\n this._isLightingLayer = layer.isLightingLayer();\n const parentRendererObject = runtimeInstanceContainerRenderer.getRendererObject();\n if (parentRendererObject) {\n parentRendererObject.addChild(this._pixiContainer);\n }\n this._pixiContainer.filters = [];\n\n // Setup rendering for lighting or 3D rendering:\n const pixiRenderer = runtimeGameRenderer.getPIXIRenderer();\n if (this._isLightingLayer) {\n this._clearColor = layer.getClearColor();\n this._setupLightingRendering(\n pixiRenderer,\n runtimeInstanceContainerRenderer\n );\n } else {\n // Clear color is used as background color of transparent sprites.\n this._clearColor = [\n ...gdjs.hexNumberToRGBArray(\n this._layer.getRuntimeScene().getBackgroundColor()\n ),\n 0,\n ];\n this._setup3DRendering(pixiRenderer, runtimeInstanceContainerRenderer);\n }\n }\n\n onCreated() {\n // The layer is now fully initialized. Adapt the 3D camera position\n // (which we could not do before in `_setup3DRendering`).\n this._update3DCameraAspectAndPosition();\n }\n\n onGameResolutionResized() {\n // Ensure the 3D camera aspect is updated:\n this._update3DCameraAspectAndPosition();\n }\n\n private _update3DCameraAspectAndPosition() {\n if (!this._threeCamera) {\n return;\n }\n if (this._threeCamera instanceof THREE.OrthographicCamera) {\n const width = this._layer.getWidth();\n const height = this._layer.getHeight();\n this._threeCamera.left = -width / 2;\n this._threeCamera.right = width / 2;\n this._threeCamera.top = height / 2;\n this._threeCamera.bottom = -height / 2;\n } else {\n this._threeCamera.aspect =\n this._layer.getWidth() / this._layer.getHeight();\n }\n this._threeCamera.updateProjectionMatrix();\n\n this.updatePosition();\n }\n\n getRendererObject(): PIXI.Container {\n return this._pixiContainer;\n }\n\n getThreeScene(): THREE.Scene | null {\n return this._threeScene;\n }\n\n getThreeCamera():\n | THREE.PerspectiveCamera\n | THREE.OrthographicCamera\n | null {\n return this._threeCamera;\n }\n\n getThreeEffectComposer(): THREE_ADDONS.EffectComposer | null {\n return this._threeEffectComposer;\n }\n\n addPostProcessingPass(pass: THREE_ADDONS.Pass) {\n if (!this._threeEffectComposer) {\n return;\n }\n const game = this._layer.getRuntimeScene().getGame();\n // TODO Keep the effects in the same order they are defined\n // because the order matter for the final result.\n // There is the same issue with 2D effects too.\n\n // The composer contains:\n // - RenderPass\n // - inserted passes for effects\n // - SMAAPass (optionally)\n // - OutputPass\n const index =\n this._threeEffectComposer.passes.length -\n (game.getAntialiasingMode() === 'none' ? 1 : 2);\n this._threeEffectComposer.insertPass(pass, index);\n }\n\n removePostProcessingPass(pass: THREE_ADDONS.Pass) {\n if (!this._threeEffectComposer) {\n return;\n }\n this._threeEffectComposer.removePass(pass);\n }\n\n hasPostProcessingPass() {\n if (!this._threeEffectComposer) {\n return false;\n }\n const game = this._layer.getRuntimeScene().getGame();\n // RenderPass, OutputPass and optionally SMAAPass are default passes.\n const emptyCount = game.getAntialiasingMode() === 'none' ? 2 : 3;\n return this._threeEffectComposer.passes.length > emptyCount;\n }\n\n /**\n * The sprite, displaying the \"render texture\" of the layer, to display\n * for a lighting layer.\n */\n getLightingSprite(): PIXI.Sprite | null {\n return this._lightingSprite;\n }\n\n /**\n * Create, or re-create, Three.js objects for 3D rendering of this layer.\n */\n private _setup3DRendering(\n pixiRenderer: PIXI.Renderer | null,\n runtimeInstanceContainerRenderer: gdjs.RuntimeInstanceContainerRenderer\n ): void {\n if (typeof THREE === 'undefined') {\n return;\n }\n // TODO (3D): ideally we would avoid the need for this check at all,\n // maybe by having separate rendering classes for custom object layers and scene layers.\n if (this._layer instanceof gdjs.Layer) {\n if (\n this._layer.getRenderingType() ===\n gdjs.RuntimeLayerRenderingType.THREE_D ||\n this._layer.getRenderingType() ===\n gdjs.RuntimeLayerRenderingType.TWO_D_PLUS_THREE_D\n ) {\n if (this._threeScene || this._threeGroup || this._threeCamera) {\n throw new Error(\n 'Tried to setup 3D rendering for a layer that is already set up.'\n );\n }\n\n this._threeScene = new THREE.Scene();\n\n // Use a mirroring on the Y axis to follow the same axis as in the 2D, PixiJS, rendering.\n // We use a mirroring rather than a camera rotation so that the Z order is not changed.\n this._threeScene.scale.y = -1;\n\n this._threeGroup = new THREE.Group();\n this._threeScene.add(this._threeGroup);\n\n if (\n this._layer.getCameraType() ===\n gdjs.RuntimeLayerCameraType.ORTHOGRAPHIC\n ) {\n const width = this._layer.getWidth();\n const height = this._layer.getHeight();\n this._threeCamera = new THREE.OrthographicCamera(\n -width / 2,\n width / 2,\n height / 2,\n -height / 2,\n this._layer.getInitialCamera3DNearPlaneDistance(),\n this._layer.getInitialCamera3DFarPlaneDistance()\n );\n } else {\n this._threeCamera = new THREE.PerspectiveCamera(\n this._layer.getInitialCamera3DFieldOfView(),\n 1,\n this._layer.getInitialCamera3DNearPlaneDistance(),\n this._layer.getInitialCamera3DFarPlaneDistance()\n );\n }\n this._threeCamera.rotation.order = 'ZYX';\n\n const game = this._layer.getRuntimeScene().getGame();\n const threeRenderer = game.getRenderer().getThreeRenderer();\n if (threeRenderer) {\n // When adding more default passes, make sure to update\n // `addPostProcessingPass` and `hasPostProcessingPass` formulas.\n this._threeEffectComposer = new THREE_ADDONS.EffectComposer(\n threeRenderer\n );\n this._threeEffectComposer.addPass(\n new THREE_ADDONS.RenderPass(this._threeScene, this._threeCamera)\n );\n if (game.getAntialiasingMode() !== 'none') {\n this._threeEffectComposer.addPass(\n new THREE_ADDONS.SMAAPass(\n game.getGameResolutionWidth(),\n game.getGameResolutionHeight()\n )\n );\n }\n this._threeEffectComposer.addPass(new THREE_ADDONS.OutputPass());\n }\n\n if (\n this._layer.getRenderingType() ===\n gdjs.RuntimeLayerRenderingType.TWO_D_PLUS_THREE_D\n ) {\n if (\n this._renderTexture ||\n this._threePlaneGeometry ||\n this._threePlaneMaterial ||\n this._threePlaneTexture ||\n this._threePlaneMesh\n )\n throw new Error(\n 'Tried to setup PixiJS plane for 2D rendering in 3D for a layer that is already set up.'\n );\n\n // If we have both 2D and 3D objects to be rendered, create a render texture that PixiJS will use\n // to render, and that will be projected on a plane by Three.js\n this._createPixiRenderTexture(pixiRenderer);\n\n // Create the plane that will show this texture.\n this._threePlaneGeometry = new THREE.PlaneGeometry(1, 1);\n\n // Create the texture to project on the plane.\n // Use a buffer to create a \"fake\" DataTexture, just so the texture\n // is considered initialized by Three.js.\n const width = 1;\n const height = 1;\n const size = width * height;\n const data = new Uint8Array(4 * size);\n const texture = new THREE.DataTexture(data, width, height);\n texture.needsUpdate = true;\n\n this._threePlaneTexture = texture;\n this._threePlaneTexture.generateMipmaps = false;\n const filter =\n this._layer.getRuntimeScene().getGame().getScaleMode() ===\n 'nearest'\n ? THREE.NearestFilter\n : THREE.LinearFilter;\n this._threePlaneTexture.minFilter = filter;\n this._threePlaneTexture.magFilter = filter;\n this._threePlaneTexture.wrapS = THREE.ClampToEdgeWrapping;\n this._threePlaneTexture.wrapT = THREE.ClampToEdgeWrapping;\n // This disable the gamma correction done by THREE as PIXI is already doing it.\n const noGammaCorrectionShader: THREE.ShaderMaterialParameters = {\n vertexShader: `\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n `,\n fragmentShader: `\n uniform sampler2D map;\n varying vec2 vUv;\n void main() {\n vec4 texel = texture2D(map, vUv);\n gl_FragColor = texel;\n }\n `,\n uniforms: {\n map: { value: this._threePlaneTexture },\n },\n side: THREE.FrontSide,\n transparent: true,\n };\n this._threePlaneMaterial = new THREE.ShaderMaterial(\n noGammaCorrectionShader\n );\n this._threePlaneMaterial;\n\n // Finally, create the mesh shown in the scene.\n this._threePlaneMesh = new THREE.Mesh(\n this._threePlaneGeometry,\n this._threePlaneMaterial\n );\n\n // Force to render the mesh last (after the rest of 3D objects, including\n // transparent ones). In most cases, the 2D rendering is composed of a lot\n // of transparent areas, and we can't risk it being displayed first and wrongly\n // occluding 3D objects shown behind.\n this._threePlaneMesh.renderOrder = Number.MAX_SAFE_INTEGER;\n this._threeScene.add(this._threePlaneMesh);\n }\n\n // Note: we can not update the position of the camera at this point,\n // because the layer might not be fully constructed.\n // See `onCreated`.\n }\n } else {\n // This is a layer of a custom object.\n\n const parentThreeObject = runtimeInstanceContainerRenderer.get3DRendererObject();\n if (!parentThreeObject) {\n // No parent 3D renderer object, 3D is disabled.\n return;\n }\n\n if (!this._threeGroup) {\n // TODO (3D) - optimization: do not create a THREE.Group if no 3D object are contained inside.\n this._threeGroup = new THREE.Group();\n parentThreeObject.add(this._threeGroup);\n }\n }\n }\n\n setThreeCameraDirty(enable: boolean) {\n this._threeCameraDirty = enable;\n }\n\n show2DRenderingPlane(enable: boolean) {\n if (!this._threePlaneMesh) return;\n if (this._threePlaneMesh.visible === enable) return;\n this._threePlaneMesh.visible = enable;\n }\n\n /**\n * Update the position of the PIXI container. To be called after each change\n * made to position, zoom or rotation of the camera.\n */\n updatePosition(): void {\n const angle = -gdjs.toRad(this._layer.getCameraRotation());\n const zoomFactor = this._layer.getCameraZoom();\n this._pixiContainer.rotation = angle;\n this._pixiContainer.scale.x = zoomFactor;\n this._pixiContainer.scale.y = zoomFactor;\n const cosValue = Math.cos(angle);\n const sinValue = Math.sin(angle);\n const centerX =\n this._layer.getCameraX() * zoomFactor * cosValue -\n this._layer.getCameraY() * zoomFactor * sinValue;\n const centerY =\n this._layer.getCameraX() * zoomFactor * sinValue +\n this._layer.getCameraY() * zoomFactor * cosValue;\n this._pixiContainer.position.x = this._layer.getWidth() / 2 - centerX;\n this._pixiContainer.position.y = this._layer.getHeight() / 2 - centerY;\n\n if (\n this._layer.getRuntimeScene().getGame().getPixelsRounding() &&\n (cosValue === 0 || sinValue === 0) &&\n Number.isInteger(zoomFactor)\n ) {\n // Camera rounding is important for pixel perfect games.\n // Otherwise, the camera position fractional part is added to\n // the sprite one and it changes in which direction sprites are rounded.\n // It makes sprites rounding inconsistent with each other\n // and they seem to move on pixel left and right.\n //\n // PIXI uses a floor function on sprites position on the screen,\n // so a floor must be applied on the camera position too.\n // According to the above calculus,\n // _pixiContainer.position is the opposite of the camera,\n // this is why the ceil function is used floor(x) = -ceil(-x).\n //\n // When the camera directly follows an object,\n // given this object dimension is even,\n // the decimal part of onScenePosition and cameraPosition are the same.\n //\n // Doing the calculus without rounding:\n // onScreenPosition = onScenePosition - cameraPosition\n // onScreenPosition = 980.75 - 200.75\n // onScreenPosition = 780\n //\n // Doing the calculus with rounding:\n // onScreenPosition = floor(onScenePosition + ceil(-cameraPosition))\n // onScreenPosition = floor(980.75 + ceil(-200.75))\n // onScreenPosition = floor(980.75 - 200)\n // onScreenPosition = floor(780.75)\n // onScreenPosition = 780\n\n if (\n this._layer\n .getRuntimeScene()\n .getGame()\n .getRenderer()\n .getPIXIRenderer() instanceof PIXI.Renderer\n ) {\n // TODO Revert from `round` to `ceil` when the issue is fixed in Pixi.\n // Since the upgrade to Pixi 7, sprites are rounded with `round`\n // instead of `floor`.\n // https://github.com/pixijs/pixijs/issues/9868\n this._pixiContainer.position.x = Math.round(\n this._pixiContainer.position.x\n );\n this._pixiContainer.position.y = Math.round(\n this._pixiContainer.position.y\n );\n } else {\n this._pixiContainer.position.x = Math.ceil(\n this._pixiContainer.position.x\n );\n this._pixiContainer.position.y = Math.ceil(\n this._pixiContainer.position.y\n );\n }\n }\n\n if (this._threeCamera) {\n // TODO (3D) - improvement: handle camera rounding like down for PixiJS?\n this._threeCamera.position.x = this._layer.getCameraX();\n this._threeCamera.position.y = -this._layer.getCameraY(); // Inverted because the scene is mirrored on Y axis.\n this._threeCamera.rotation.z = angle;\n\n if (this._threeCamera instanceof THREE.OrthographicCamera) {\n this._threeCamera.zoom = this._layer.getCameraZoom();\n this._threeCamera.updateProjectionMatrix();\n this._threeCamera.position.z = this._layer.getCameraZ(null);\n } else {\n this._threeCamera.position.z = this._layer.getCameraZ(\n this._threeCamera.fov\n );\n }\n\n if (this._threePlaneMesh) {\n // Adapt the plane size so that it covers the whole screen.\n this._threePlaneMesh.scale.x = this._layer.getWidth() / zoomFactor;\n this._threePlaneMesh.scale.y = this._layer.getHeight() / zoomFactor;\n\n // Adapt the plane position so that it's always displayed on the whole screen.\n this._threePlaneMesh.position.x = this._threeCamera.position.x;\n this._threePlaneMesh.position.y = -this._threeCamera.position.y; // Inverted because the scene is mirrored on Y axis.\n this._threePlaneMesh.rotation.z = -angle;\n }\n }\n }\n\n updateResolution() {\n if (this._threeEffectComposer) {\n const game = this._layer.getRuntimeScene().getGame();\n this._threeEffectComposer.setSize(\n game.getGameResolutionWidth(),\n game.getGameResolutionHeight()\n );\n }\n }\n\n isCameraRotatedIn3D() {\n return (\n this._threeCamera &&\n (this._threeCamera.rotation.x !== 0 ||\n this._threeCamera.rotation.y !== 0)\n );\n }\n\n transformTo3DWorld(\n screenX: float,\n screenY: float,\n worldZ: float,\n cameraId: integer,\n result: FloatPoint\n ): FloatPoint {\n const camera = this._threeCamera;\n if (!camera) {\n result[0] = 0;\n result[1] = 0;\n return result;\n }\n const width = this._layer.getWidth();\n const height = this._layer.getHeight();\n const normalizedX = (screenX / width) * 2 - 1;\n const normalizedY = -(screenY / height) * 2 + 1;\n\n let vector = LayerPixiRenderer.vectorForProjections;\n if (!vector) {\n vector = new THREE.Vector3();\n LayerPixiRenderer.vectorForProjections = vector;\n }\n\n camera.updateMatrixWorld();\n\n if (camera instanceof THREE.OrthographicCamera) {\n // https://discourse.threejs.org/t/how-to-unproject-mouse2d-with-orthographic-camera/4777\n vector.set(normalizedX, normalizedY, 0);\n vector.unproject(camera);\n // The unprojected point is on the camera.\n // Find x and y for a given z along the camera direction line.\n const direction = new THREE.Vector3();\n camera.getWorldDirection(direction);\n const distance = (worldZ - vector.z) / direction.z;\n vector.x += distance * direction.x;\n vector.y += distance * direction.y;\n } else {\n // https://stackoverflow.com/questions/13055214/mouse-canvas-x-y-to-three-js-world-x-y-z\n vector.set(normalizedX, normalizedY, 0.5);\n vector.unproject(camera);\n // The unprojected point is on the frustum plane.\n // Find x and y for a given z along the line between the camera and\n // the one on the frustum.\n vector.sub(camera.position).normalize();\n const distance = (worldZ - camera.position.z) / vector.z;\n vector.x = distance * vector.x + camera.position.x;\n vector.y = distance * vector.y + camera.position.y;\n }\n\n // The plane z == worldZ may not be visible on the camera.\n if (!Number.isFinite(vector.x) || !Number.isFinite(vector.y)) {\n result[0] = 0;\n result[1] = 0;\n return result;\n }\n\n result[0] = vector.x;\n result[1] = -vector.y;\n return result;\n }\n\n updateVisibility(visible: boolean): void {\n this._pixiContainer.visible = !!visible;\n if (this._threeGroup) this._threeGroup.visible = !!visible;\n }\n\n updatePreRender(): void {\n if (this._threeCameraDirty) {\n const camera = this.getThreeCamera();\n if (camera) {\n camera.updateProjectionMatrix();\n }\n this._threeCameraDirty = false;\n }\n }\n\n /**\n * Add a child to the pixi container associated to the layer.\n * All objects which are on this layer must be children of this container.\n *\n * @param pixiChild The child (PIXI object) to be added.\n * @param zOrder The z order of the associated object.\n */\n addRendererObject(pixiChild, zOrder: float): void {\n const child = pixiChild as PIXI.DisplayObject;\n child.zIndex = zOrder || LayerPixiRenderer.zeroZOrderForPixi;\n this._pixiContainer.addChild(child);\n }\n\n /**\n * Change the z order of a child associated to an object.\n *\n * @param pixiChild The child (PIXI object) to be modified.\n * @param newZOrder The z order of the associated object.\n */\n changeRendererObjectZOrder(pixiChild, newZOrder: float): void {\n const child = pixiChild as PIXI.DisplayObject;\n child.zIndex = newZOrder;\n }\n\n /**\n * Remove a child from the internal pixi container.\n * Should be called when an object is deleted or removed from the layer.\n *\n * @param child The child (PIXI object) to be removed.\n */\n removeRendererObject(child): void {\n this._pixiContainer.removeChild(child);\n }\n\n has3DObjects(): boolean {\n return !!this._threeGroup && this._threeGroup.children.length > 0;\n }\n\n has2DObjects(): boolean {\n return this._pixiContainer.children.length > 0;\n }\n\n add3DRendererObject(object: THREE.Object3D): void {\n if (!this._threeGroup) return;\n\n this._threeGroup.add(object);\n }\n\n remove3DRendererObject(object: THREE.Object3D): void {\n if (!this._threeGroup) return;\n\n this._threeGroup.remove(object);\n }\n\n updateClearColor(): void {\n this._clearColor = this._layer.getClearColor();\n // this._createPixiRenderTexture(); // TODO: Check this was useless\n }\n\n /**\n * Create the PixiJS RenderTexture used to display the whole layer.\n * Can be used either for lighting or for rendering the layer in a texture\n * so it can then be consumed by Three.js to render it in 3D.\n */\n private _createPixiRenderTexture(pixiRenderer: PIXI.Renderer | null): void {\n if (!pixiRenderer || pixiRenderer.type !== PIXI.RENDERER_TYPE.WEBGL) {\n return;\n }\n if (this._renderTexture) {\n logger.error(\n 'Tried to create a PixiJS RenderTexture for a layer that already has one.'\n );\n return;\n }\n\n this._oldWidth = pixiRenderer.screen.width;\n this._oldHeight = pixiRenderer.screen.height;\n const width = this._oldWidth;\n const height = this._oldHeight;\n const resolution = pixiRenderer.resolution;\n this._renderTexture = PIXI.RenderTexture.create({\n // A size of 0 is forbidden by Pixi.\n width: width || 100,\n height: height || 100,\n resolution,\n });\n this._renderTexture.baseTexture.scaleMode = PIXI.SCALE_MODES.LINEAR;\n logger.info(`RenderTexture created for layer ${this._layer.getName()}.`);\n }\n\n /**\n * Render the layer of the PixiJS RenderTexture, so that it can be then displayed\n * with a blend mode (for a lighting layer) or consumed by Three.js (for 2D+3D layers).\n */\n renderOnPixiRenderTexture(pixiRenderer: PIXI.Renderer) {\n if (!this._renderTexture) {\n return;\n }\n if (\n this._oldWidth !== pixiRenderer.screen.width ||\n this._oldHeight !== pixiRenderer.screen.height\n ) {\n // A size of 0 is forbidden by Pixi.\n this._renderTexture.resize(\n pixiRenderer.screen.width || 100,\n pixiRenderer.screen.height || 100\n );\n this._oldWidth = pixiRenderer.screen.width;\n this._oldHeight = pixiRenderer.screen.height;\n }\n const oldRenderTexture = pixiRenderer.renderTexture.current || undefined;\n const oldSourceFrame = pixiRenderer.renderTexture.sourceFrame;\n pixiRenderer.renderTexture.bind(this._renderTexture);\n\n // The background is the ambient color for lighting layers\n // and transparent for 2D+3D layers.\n this._clearColor[3] = this._isLightingLayer ? 1 : 0;\n pixiRenderer.renderTexture.clear(this._clearColor);\n\n pixiRenderer.render(this._pixiContainer, {\n renderTexture: this._renderTexture,\n clear: false,\n });\n pixiRenderer.renderTexture.bind(\n oldRenderTexture,\n oldSourceFrame,\n undefined\n );\n }\n\n /**\n * Set the texture of the 2D plane in the 3D world to be the same WebGL texture\n * as the PixiJS RenderTexture - so that the 2D rendering can be shown in the 3D world.\n */\n updateThreePlaneTextureFromPixiRenderTexture(\n threeRenderer: THREE.WebGLRenderer,\n pixiRenderer: PIXI.Renderer\n ): void {\n if (!this._threePlaneTexture || !this._renderTexture) {\n return;\n }\n\n const glTexture = this._renderTexture.baseTexture._glTextures[\n pixiRenderer.CONTEXT_UID\n ];\n if (glTexture) {\n // \"Hack\" into the Three.js renderer by getting the internal WebGL texture for the PixiJS plane,\n // and set it so that it's the same as the WebGL texture for the PixiJS RenderTexture.\n // This works because PixiJS and Three.js are using the same WebGL context.\n const texture = threeRenderer.properties.get(this._threePlaneTexture);\n texture.__webglTexture = glTexture.texture;\n }\n }\n\n /**\n * Enable the use of a PIXI.RenderTexture to render the PIXI.Container\n * of the layer and, in the scene PIXI container, replace the container\n * of the layer by a sprite showing this texture.\n * used only in lighting for now as the sprite could have MULTIPLY blend mode.\n */\n private _setupLightingRendering(\n pixiRenderer: PIXI.Renderer | null,\n runtimeInstanceContainerRenderer: gdjs.RuntimeInstanceContainerRenderer\n ): void {\n this._createPixiRenderTexture(pixiRenderer);\n if (!this._renderTexture) {\n return;\n }\n\n this._lightingSprite = new PIXI.Sprite(this._renderTexture);\n this._lightingSprite.blendMode = PIXI.BLEND_MODES.MULTIPLY;\n const parentPixiContainer = runtimeInstanceContainerRenderer.getRendererObject();\n if (parentPixiContainer) {\n const index = parentPixiContainer.getChildIndex(this._pixiContainer);\n parentPixiContainer.addChildAt(this._lightingSprite, index);\n parentPixiContainer.removeChild(this._pixiContainer);\n }\n }\n }\n\n //Register the class to let the engine use it.\n export type LayerRenderer = gdjs.LayerPixiRenderer;\n export const LayerRenderer = gdjs.LayerPixiRenderer;\n}\n"],
|
|
5
|
-
"mappings": "AAMA,GAAU,MAAV,UAAU,EAAV,CACE,KAAM,GAAS,GAAI,GAAK,OAAO,qBAKxB,OAAwB,CAiD7B,YACE,EACA,EACA,EACA,CA/CM,qBAAsC,KAStC,oBAA4C,KAG5C,eAA0B,KAC1B,gBAA2B,KAG3B,iBAAkC,KAClC,iBAAkC,KAClC,kBAGG,KACH,uBAA6B,GAC7B,0BAA2D,KAI3D,wBAA2C,KAC3C,yBAAkD,KAClD,yBAAmD,KACnD,qBAAqC,KAkB3C,KAAK,eAAiB,GAAI,MAAK,UAC/B,KAAK,eAAe,iBAAmB,GACvC,KAAK,OAAS,EACd,KAAK,iBAAmB,EAAM,kBAC9B,KAAM,
|
|
4
|
+
"sourcesContent": ["/*\n * GDevelop JS Platform\n * Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.\n * This project is released under the MIT License.\n */\n\nnamespace gdjs {\n const logger = new gdjs.Logger('LayerPixiRenderer');\n\n /**\n * The renderer for a gdjs.Layer using Pixi.js.\n */\n export class LayerPixiRenderer {\n private _pixiContainer: PIXI.Container;\n\n private _layer: gdjs.RuntimeLayer;\n\n /** For a lighting layer, the sprite used to display the render texture. */\n private _lightingSprite: PIXI.Sprite | null = null;\n private _isLightingLayer: boolean;\n private _clearColor: Array<integer>;\n\n /**\n * The render texture where the whole 2D layer is rendered.\n * The render texture is then used for lighting (if it's a light layer)\n * or to be rendered in a 3D scene (for a 2D+3D layer).\n */\n private _renderTexture: PIXI.RenderTexture | null = null;\n\n // Width and height are tracked when a render texture is used.\n private _oldWidth: float | null = null;\n private _oldHeight: float | null = null;\n\n // For a 3D (or 2D+3D) layer:\n private _threeGroup: THREE.Group | null = null;\n private _threeScene: THREE.Scene | null = null;\n private _threeCamera:\n | THREE.PerspectiveCamera\n | THREE.OrthographicCamera\n | null = null;\n private _threeCameraDirty: boolean = false;\n private _threeEffectComposer: THREE_ADDONS.EffectComposer | null = null;\n\n // For a 2D+3D layer, the 2D rendering is done on the render texture\n // and then must be displayed on a plane in the 3D world:\n private _threePlaneTexture: THREE.Texture | null = null;\n private _threePlaneGeometry: THREE.PlaneGeometry | null = null;\n private _threePlaneMaterial: THREE.ShaderMaterial | null = null;\n private _threePlaneMesh: THREE.Mesh | null = null;\n\n /**\n * Pixi doesn't sort children with zIndex == 0.\n */\n private static readonly zeroZOrderForPixi = Math.pow(2, -24);\n\n private static vectorForProjections: THREE.Vector3 | null = null;\n\n /**\n * @param layer The layer\n * @param runtimeInstanceContainerRenderer The scene renderer\n */\n constructor(\n layer: gdjs.RuntimeLayer,\n runtimeInstanceContainerRenderer: gdjs.RuntimeInstanceContainerRenderer,\n runtimeGameRenderer: gdjs.RuntimeGameRenderer\n ) {\n this._pixiContainer = new PIXI.Container();\n this._pixiContainer.sortableChildren = true;\n this._layer = layer;\n this._isLightingLayer = layer.isLightingLayer();\n const parentRendererObject =\n runtimeInstanceContainerRenderer.getRendererObject();\n if (parentRendererObject) {\n parentRendererObject.addChild(this._pixiContainer);\n }\n this._pixiContainer.filters = [];\n\n // Setup rendering for lighting or 3D rendering:\n const pixiRenderer = runtimeGameRenderer.getPIXIRenderer();\n if (this._isLightingLayer) {\n this._clearColor = layer.getClearColor();\n this._setupLightingRendering(\n pixiRenderer,\n runtimeInstanceContainerRenderer\n );\n } else {\n // Clear color is used as background color of transparent sprites.\n this._clearColor = [\n ...gdjs.hexNumberToRGBArray(\n this._layer.getRuntimeScene().getBackgroundColor()\n ),\n 0,\n ];\n this._setup3DRendering(pixiRenderer, runtimeInstanceContainerRenderer);\n }\n }\n\n onCreated() {\n // The layer is now fully initialized. Adapt the 3D camera position\n // (which we could not do before in `_setup3DRendering`).\n this._update3DCameraAspectAndPosition();\n }\n\n onGameResolutionResized() {\n // Ensure the 3D camera aspect is updated:\n this._update3DCameraAspectAndPosition();\n }\n\n private _update3DCameraAspectAndPosition() {\n if (!this._threeCamera) {\n return;\n }\n if (this._threeCamera instanceof THREE.OrthographicCamera) {\n const width = this._layer.getWidth();\n const height = this._layer.getHeight();\n this._threeCamera.left = -width / 2;\n this._threeCamera.right = width / 2;\n this._threeCamera.top = height / 2;\n this._threeCamera.bottom = -height / 2;\n } else {\n this._threeCamera.aspect =\n this._layer.getWidth() / this._layer.getHeight();\n }\n this._threeCamera.updateProjectionMatrix();\n\n this.updatePosition();\n }\n\n getRendererObject(): PIXI.Container {\n return this._pixiContainer;\n }\n\n getThreeScene(): THREE.Scene | null {\n return this._threeScene;\n }\n\n getThreeCamera():\n | THREE.PerspectiveCamera\n | THREE.OrthographicCamera\n | null {\n return this._threeCamera;\n }\n\n getThreeEffectComposer(): THREE_ADDONS.EffectComposer | null {\n return this._threeEffectComposer;\n }\n\n addPostProcessingPass(pass: THREE_ADDONS.Pass) {\n if (!this._threeEffectComposer) {\n return;\n }\n const game = this._layer.getRuntimeScene().getGame();\n // TODO Keep the effects in the same order they are defined\n // because the order matter for the final result.\n // There is the same issue with 2D effects too.\n\n // The composer contains:\n // - RenderPass\n // - inserted passes for effects\n // - SMAAPass (optionally)\n // - OutputPass\n const index =\n this._threeEffectComposer.passes.length -\n (game.getAntialiasingMode() === 'none' ? 1 : 2);\n this._threeEffectComposer.insertPass(pass, index);\n }\n\n removePostProcessingPass(pass: THREE_ADDONS.Pass) {\n if (!this._threeEffectComposer) {\n return;\n }\n this._threeEffectComposer.removePass(pass);\n }\n\n hasPostProcessingPass() {\n if (!this._threeEffectComposer) {\n return false;\n }\n const game = this._layer.getRuntimeScene().getGame();\n // RenderPass, OutputPass and optionally SMAAPass are default passes.\n const emptyCount = game.getAntialiasingMode() === 'none' ? 2 : 3;\n return this._threeEffectComposer.passes.length > emptyCount;\n }\n\n /**\n * The sprite, displaying the \"render texture\" of the layer, to display\n * for a lighting layer.\n */\n getLightingSprite(): PIXI.Sprite | null {\n return this._lightingSprite;\n }\n\n /**\n * Create, or re-create, Three.js objects for 3D rendering of this layer.\n */\n private _setup3DRendering(\n pixiRenderer: PIXI.Renderer | null,\n runtimeInstanceContainerRenderer: gdjs.RuntimeInstanceContainerRenderer\n ): void {\n if (typeof THREE === 'undefined') {\n return;\n }\n // TODO (3D): ideally we would avoid the need for this check at all,\n // maybe by having separate rendering classes for custom object layers and scene layers.\n if (this._layer instanceof gdjs.Layer) {\n if (\n this._layer.getRenderingType() ===\n gdjs.RuntimeLayerRenderingType.THREE_D ||\n this._layer.getRenderingType() ===\n gdjs.RuntimeLayerRenderingType.TWO_D_PLUS_THREE_D\n ) {\n if (this._threeScene || this._threeGroup || this._threeCamera) {\n throw new Error(\n 'Tried to setup 3D rendering for a layer that is already set up.'\n );\n }\n\n this._threeScene = new THREE.Scene();\n\n // Use a mirroring on the Y axis to follow the same axis as in the 2D, PixiJS, rendering.\n // We use a mirroring rather than a camera rotation so that the Z order is not changed.\n this._threeScene.scale.y = -1;\n\n this._threeGroup = new THREE.Group();\n this._threeScene.add(this._threeGroup);\n\n if (\n this._layer.getCameraType() ===\n gdjs.RuntimeLayerCameraType.ORTHOGRAPHIC\n ) {\n const width = this._layer.getWidth();\n const height = this._layer.getHeight();\n this._threeCamera = new THREE.OrthographicCamera(\n -width / 2,\n width / 2,\n height / 2,\n -height / 2,\n this._layer.getInitialCamera3DNearPlaneDistance(),\n this._layer.getInitialCamera3DFarPlaneDistance()\n );\n } else {\n this._threeCamera = new THREE.PerspectiveCamera(\n this._layer.getInitialCamera3DFieldOfView(),\n 1,\n this._layer.getInitialCamera3DNearPlaneDistance(),\n this._layer.getInitialCamera3DFarPlaneDistance()\n );\n }\n this._threeCamera.rotation.order = 'ZYX';\n\n const game = this._layer.getRuntimeScene().getGame();\n const threeRenderer = game.getRenderer().getThreeRenderer();\n if (threeRenderer) {\n // When adding more default passes, make sure to update\n // `addPostProcessingPass` and `hasPostProcessingPass` formulas.\n this._threeEffectComposer = new THREE_ADDONS.EffectComposer(\n threeRenderer\n );\n this._threeEffectComposer.addPass(\n new THREE_ADDONS.RenderPass(this._threeScene, this._threeCamera)\n );\n if (game.getAntialiasingMode() !== 'none') {\n this._threeEffectComposer.addPass(\n new THREE_ADDONS.SMAAPass(\n game.getGameResolutionWidth(),\n game.getGameResolutionHeight()\n )\n );\n }\n this._threeEffectComposer.addPass(new THREE_ADDONS.OutputPass());\n }\n\n if (\n this._layer.getRenderingType() ===\n gdjs.RuntimeLayerRenderingType.TWO_D_PLUS_THREE_D\n ) {\n if (\n this._renderTexture ||\n this._threePlaneGeometry ||\n this._threePlaneMaterial ||\n this._threePlaneTexture ||\n this._threePlaneMesh\n )\n throw new Error(\n 'Tried to setup PixiJS plane for 2D rendering in 3D for a layer that is already set up.'\n );\n\n // If we have both 2D and 3D objects to be rendered, create a render texture that PixiJS will use\n // to render, and that will be projected on a plane by Three.js\n this._createPixiRenderTexture(pixiRenderer);\n\n // Create the plane that will show this texture.\n this._threePlaneGeometry = new THREE.PlaneGeometry(1, 1);\n\n // Create the texture to project on the plane.\n // Use a buffer to create a \"fake\" DataTexture, just so the texture\n // is considered initialized by Three.js.\n const width = 1;\n const height = 1;\n const size = width * height;\n const data = new Uint8Array(4 * size);\n const texture = new THREE.DataTexture(data, width, height);\n texture.needsUpdate = true;\n\n this._threePlaneTexture = texture;\n this._threePlaneTexture.generateMipmaps = false;\n const filter =\n this._layer.getRuntimeScene().getGame().getScaleMode() ===\n 'nearest'\n ? THREE.NearestFilter\n : THREE.LinearFilter;\n this._threePlaneTexture.minFilter = filter;\n this._threePlaneTexture.magFilter = filter;\n this._threePlaneTexture.wrapS = THREE.ClampToEdgeWrapping;\n this._threePlaneTexture.wrapT = THREE.ClampToEdgeWrapping;\n // This disable the gamma correction done by THREE as PIXI is already doing it.\n const noGammaCorrectionShader: THREE.ShaderMaterialParameters = {\n vertexShader: `\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n `,\n fragmentShader: `\n uniform sampler2D map;\n varying vec2 vUv;\n void main() {\n vec4 texel = texture2D(map, vUv);\n gl_FragColor = texel;\n }\n `,\n uniforms: {\n map: { value: this._threePlaneTexture },\n },\n side: THREE.FrontSide,\n transparent: true,\n };\n this._threePlaneMaterial = new THREE.ShaderMaterial(\n noGammaCorrectionShader\n );\n this._threePlaneMaterial;\n\n // Finally, create the mesh shown in the scene.\n this._threePlaneMesh = new THREE.Mesh(\n this._threePlaneGeometry,\n this._threePlaneMaterial\n );\n\n // Force to render the mesh last (after the rest of 3D objects, including\n // transparent ones). In most cases, the 2D rendering is composed of a lot\n // of transparent areas, and we can't risk it being displayed first and wrongly\n // occluding 3D objects shown behind.\n this._threePlaneMesh.renderOrder = Number.MAX_SAFE_INTEGER;\n this._threeScene.add(this._threePlaneMesh);\n }\n\n // Note: we can not update the position of the camera at this point,\n // because the layer might not be fully constructed.\n // See `onCreated`.\n }\n } else {\n // This is a layer of a custom object.\n\n const parentThreeObject =\n runtimeInstanceContainerRenderer.get3DRendererObject();\n if (!parentThreeObject) {\n // No parent 3D renderer object, 3D is disabled.\n return;\n }\n\n if (!this._threeGroup) {\n // TODO (3D) - optimization: do not create a THREE.Group if no 3D object are contained inside.\n this._threeGroup = new THREE.Group();\n parentThreeObject.add(this._threeGroup);\n }\n }\n }\n\n setThreeCameraDirty(enable: boolean) {\n this._threeCameraDirty = enable;\n }\n\n show2DRenderingPlane(enable: boolean) {\n if (!this._threePlaneMesh) return;\n if (this._threePlaneMesh.visible === enable) return;\n this._threePlaneMesh.visible = enable;\n }\n\n /**\n * Update the position of the PIXI container. To be called after each change\n * made to position, zoom or rotation of the camera.\n */\n updatePosition(): void {\n const angle = -gdjs.toRad(this._layer.getCameraRotation());\n const zoomFactor = this._layer.getCameraZoom();\n this._pixiContainer.rotation = angle;\n this._pixiContainer.scale.x = zoomFactor;\n this._pixiContainer.scale.y = zoomFactor;\n const cosValue = Math.cos(angle);\n const sinValue = Math.sin(angle);\n const centerX =\n this._layer.getCameraX() * zoomFactor * cosValue -\n this._layer.getCameraY() * zoomFactor * sinValue;\n const centerY =\n this._layer.getCameraX() * zoomFactor * sinValue +\n this._layer.getCameraY() * zoomFactor * cosValue;\n this._pixiContainer.position.x = this._layer.getWidth() / 2 - centerX;\n this._pixiContainer.position.y = this._layer.getHeight() / 2 - centerY;\n\n if (\n this._layer.getRuntimeScene().getGame().getPixelsRounding() &&\n (cosValue === 0 || sinValue === 0) &&\n Number.isInteger(zoomFactor)\n ) {\n // Camera rounding is important for pixel perfect games.\n // Otherwise, the camera position fractional part is added to\n // the sprite one and it changes in which direction sprites are rounded.\n // It makes sprites rounding inconsistent with each other\n // and they seem to move on pixel left and right.\n //\n // PIXI uses a floor function on sprites position on the screen,\n // so a floor must be applied on the camera position too.\n // According to the above calculus,\n // _pixiContainer.position is the opposite of the camera,\n // this is why the ceil function is used floor(x) = -ceil(-x).\n //\n // When the camera directly follows an object,\n // given this object dimension is even,\n // the decimal part of onScenePosition and cameraPosition are the same.\n //\n // Doing the calculus without rounding:\n // onScreenPosition = onScenePosition - cameraPosition\n // onScreenPosition = 980.75 - 200.75\n // onScreenPosition = 780\n //\n // Doing the calculus with rounding:\n // onScreenPosition = floor(onScenePosition + ceil(-cameraPosition))\n // onScreenPosition = floor(980.75 + ceil(-200.75))\n // onScreenPosition = floor(980.75 - 200)\n // onScreenPosition = floor(780.75)\n // onScreenPosition = 780\n\n if (\n this._layer\n .getRuntimeScene()\n .getGame()\n .getRenderer()\n .getPIXIRenderer() instanceof PIXI.Renderer\n ) {\n // TODO Revert from `round` to `ceil` when the issue is fixed in Pixi.\n // Since the upgrade to Pixi 7, sprites are rounded with `round`\n // instead of `floor`.\n // https://github.com/pixijs/pixijs/issues/9868\n this._pixiContainer.position.x = Math.round(\n this._pixiContainer.position.x\n );\n this._pixiContainer.position.y = Math.round(\n this._pixiContainer.position.y\n );\n } else {\n this._pixiContainer.position.x = Math.ceil(\n this._pixiContainer.position.x\n );\n this._pixiContainer.position.y = Math.ceil(\n this._pixiContainer.position.y\n );\n }\n }\n\n if (this._threeCamera) {\n // TODO (3D) - improvement: handle camera rounding like down for PixiJS?\n this._threeCamera.position.x = this._layer.getCameraX();\n this._threeCamera.position.y = -this._layer.getCameraY(); // Inverted because the scene is mirrored on Y axis.\n this._threeCamera.rotation.z = angle;\n\n if (this._threeCamera instanceof THREE.OrthographicCamera) {\n this._threeCamera.zoom = this._layer.getCameraZoom();\n this._threeCamera.updateProjectionMatrix();\n this._threeCamera.position.z = this._layer.getCameraZ(null);\n } else {\n this._threeCamera.position.z = this._layer.getCameraZ(\n this._threeCamera.fov\n );\n }\n\n if (this._threePlaneMesh) {\n // Adapt the plane size so that it covers the whole screen.\n this._threePlaneMesh.scale.x = this._layer.getWidth() / zoomFactor;\n this._threePlaneMesh.scale.y = this._layer.getHeight() / zoomFactor;\n\n // Adapt the plane position so that it's always displayed on the whole screen.\n this._threePlaneMesh.position.x = this._threeCamera.position.x;\n this._threePlaneMesh.position.y = -this._threeCamera.position.y; // Inverted because the scene is mirrored on Y axis.\n this._threePlaneMesh.rotation.z = -angle;\n }\n }\n }\n\n updateResolution() {\n if (this._threeEffectComposer) {\n const game = this._layer.getRuntimeScene().getGame();\n this._threeEffectComposer.setSize(\n game.getGameResolutionWidth(),\n game.getGameResolutionHeight()\n );\n }\n }\n\n isCameraRotatedIn3D() {\n return (\n this._threeCamera &&\n (this._threeCamera.rotation.x !== 0 ||\n this._threeCamera.rotation.y !== 0)\n );\n }\n\n transformTo3DWorld(\n screenX: float,\n screenY: float,\n worldZ: float,\n cameraId: integer,\n result: FloatPoint\n ): FloatPoint {\n const camera = this._threeCamera;\n if (!camera) {\n result[0] = 0;\n result[1] = 0;\n return result;\n }\n const width = this._layer.getWidth();\n const height = this._layer.getHeight();\n const normalizedX = (screenX / width) * 2 - 1;\n const normalizedY = -(screenY / height) * 2 + 1;\n\n let vector = LayerPixiRenderer.vectorForProjections;\n if (!vector) {\n vector = new THREE.Vector3();\n LayerPixiRenderer.vectorForProjections = vector;\n }\n\n camera.updateMatrixWorld();\n\n if (camera instanceof THREE.OrthographicCamera) {\n // https://discourse.threejs.org/t/how-to-unproject-mouse2d-with-orthographic-camera/4777\n vector.set(normalizedX, normalizedY, 0);\n vector.unproject(camera);\n // The unprojected point is on the camera.\n // Find x and y for a given z along the camera direction line.\n const direction = new THREE.Vector3();\n camera.getWorldDirection(direction);\n const distance = (worldZ - vector.z) / direction.z;\n vector.x += distance * direction.x;\n vector.y += distance * direction.y;\n } else {\n // https://stackoverflow.com/questions/13055214/mouse-canvas-x-y-to-three-js-world-x-y-z\n vector.set(normalizedX, normalizedY, 0.5);\n vector.unproject(camera);\n // The unprojected point is on the frustum plane.\n // Find x and y for a given z along the line between the camera and\n // the one on the frustum.\n vector.sub(camera.position).normalize();\n const distance = (worldZ - camera.position.z) / vector.z;\n vector.x = distance * vector.x + camera.position.x;\n vector.y = distance * vector.y + camera.position.y;\n }\n\n // The plane z == worldZ may not be visible on the camera.\n if (!Number.isFinite(vector.x) || !Number.isFinite(vector.y)) {\n result[0] = 0;\n result[1] = 0;\n return result;\n }\n\n result[0] = vector.x;\n result[1] = -vector.y;\n return result;\n }\n\n updateVisibility(visible: boolean): void {\n this._pixiContainer.visible = !!visible;\n if (this._threeGroup) this._threeGroup.visible = !!visible;\n }\n\n updatePreRender(): void {\n if (this._threeCameraDirty) {\n const camera = this.getThreeCamera();\n if (camera) {\n camera.updateProjectionMatrix();\n }\n this._threeCameraDirty = false;\n }\n }\n\n /**\n * Add a child to the pixi container associated to the layer.\n * All objects which are on this layer must be children of this container.\n *\n * @param pixiChild The child (PIXI object) to be added.\n * @param zOrder The z order of the associated object.\n */\n addRendererObject(pixiChild, zOrder: float): void {\n const child = pixiChild as PIXI.DisplayObject;\n child.zIndex = zOrder || LayerPixiRenderer.zeroZOrderForPixi;\n this._pixiContainer.addChild(child);\n }\n\n /**\n * Change the z order of a child associated to an object.\n *\n * @param pixiChild The child (PIXI object) to be modified.\n * @param newZOrder The z order of the associated object.\n */\n changeRendererObjectZOrder(pixiChild, newZOrder: float): void {\n const child = pixiChild as PIXI.DisplayObject;\n child.zIndex = newZOrder;\n }\n\n /**\n * Remove a child from the internal pixi container.\n * Should be called when an object is deleted or removed from the layer.\n *\n * @param child The child (PIXI object) to be removed.\n */\n removeRendererObject(child): void {\n this._pixiContainer.removeChild(child);\n }\n\n has3DObjects(): boolean {\n return !!this._threeGroup && this._threeGroup.children.length > 0;\n }\n\n has2DObjects(): boolean {\n return this._pixiContainer.children.length > 0;\n }\n\n add3DRendererObject(object: THREE.Object3D): void {\n if (!this._threeGroup) return;\n\n this._threeGroup.add(object);\n }\n\n remove3DRendererObject(object: THREE.Object3D): void {\n if (!this._threeGroup) return;\n\n this._threeGroup.remove(object);\n }\n\n updateClearColor(): void {\n this._clearColor = this._layer.getClearColor();\n // this._createPixiRenderTexture(); // TODO: Check this was useless\n }\n\n /**\n * Create the PixiJS RenderTexture used to display the whole layer.\n * Can be used either for lighting or for rendering the layer in a texture\n * so it can then be consumed by Three.js to render it in 3D.\n */\n private _createPixiRenderTexture(pixiRenderer: PIXI.Renderer | null): void {\n if (!pixiRenderer || pixiRenderer.type !== PIXI.RENDERER_TYPE.WEBGL) {\n return;\n }\n if (this._renderTexture) {\n logger.error(\n 'Tried to create a PixiJS RenderTexture for a layer that already has one.'\n );\n return;\n }\n\n this._oldWidth = pixiRenderer.screen.width;\n this._oldHeight = pixiRenderer.screen.height;\n const width = this._oldWidth;\n const height = this._oldHeight;\n const resolution = pixiRenderer.resolution;\n this._renderTexture = PIXI.RenderTexture.create({\n // A size of 0 is forbidden by Pixi.\n width: width || 100,\n height: height || 100,\n resolution,\n });\n this._renderTexture.baseTexture.scaleMode = PIXI.SCALE_MODES.LINEAR;\n logger.info(`RenderTexture created for layer ${this._layer.getName()}.`);\n }\n\n /**\n * Render the layer of the PixiJS RenderTexture, so that it can be then displayed\n * with a blend mode (for a lighting layer) or consumed by Three.js (for 2D+3D layers).\n */\n renderOnPixiRenderTexture(pixiRenderer: PIXI.Renderer) {\n if (!this._renderTexture) {\n return;\n }\n if (\n this._oldWidth !== pixiRenderer.screen.width ||\n this._oldHeight !== pixiRenderer.screen.height\n ) {\n // A size of 0 is forbidden by Pixi.\n this._renderTexture.resize(\n pixiRenderer.screen.width || 100,\n pixiRenderer.screen.height || 100\n );\n this._oldWidth = pixiRenderer.screen.width;\n this._oldHeight = pixiRenderer.screen.height;\n }\n const oldRenderTexture = pixiRenderer.renderTexture.current || undefined;\n const oldSourceFrame = pixiRenderer.renderTexture.sourceFrame;\n pixiRenderer.renderTexture.bind(this._renderTexture);\n\n // The background is the ambient color for lighting layers\n // and transparent for 2D+3D layers.\n this._clearColor[3] = this._isLightingLayer ? 1 : 0;\n pixiRenderer.renderTexture.clear(this._clearColor);\n\n pixiRenderer.render(this._pixiContainer, {\n renderTexture: this._renderTexture,\n clear: false,\n });\n pixiRenderer.renderTexture.bind(\n oldRenderTexture,\n oldSourceFrame,\n undefined\n );\n }\n\n /**\n * Set the texture of the 2D plane in the 3D world to be the same WebGL texture\n * as the PixiJS RenderTexture - so that the 2D rendering can be shown in the 3D world.\n */\n updateThreePlaneTextureFromPixiRenderTexture(\n threeRenderer: THREE.WebGLRenderer,\n pixiRenderer: PIXI.Renderer\n ): void {\n if (!this._threePlaneTexture || !this._renderTexture) {\n return;\n }\n\n const glTexture =\n this._renderTexture.baseTexture._glTextures[pixiRenderer.CONTEXT_UID];\n if (glTexture) {\n // \"Hack\" into the Three.js renderer by getting the internal WebGL texture for the PixiJS plane,\n // and set it so that it's the same as the WebGL texture for the PixiJS RenderTexture.\n // This works because PixiJS and Three.js are using the same WebGL context.\n const texture = threeRenderer.properties.get(this._threePlaneTexture);\n texture.__webglTexture = glTexture.texture;\n }\n }\n\n /**\n * Enable the use of a PIXI.RenderTexture to render the PIXI.Container\n * of the layer and, in the scene PIXI container, replace the container\n * of the layer by a sprite showing this texture.\n * used only in lighting for now as the sprite could have MULTIPLY blend mode.\n */\n private _setupLightingRendering(\n pixiRenderer: PIXI.Renderer | null,\n runtimeInstanceContainerRenderer: gdjs.RuntimeInstanceContainerRenderer\n ): void {\n this._createPixiRenderTexture(pixiRenderer);\n if (!this._renderTexture) {\n return;\n }\n\n this._lightingSprite = new PIXI.Sprite(this._renderTexture);\n this._lightingSprite.blendMode = PIXI.BLEND_MODES.MULTIPLY;\n const parentPixiContainer =\n runtimeInstanceContainerRenderer.getRendererObject();\n if (parentPixiContainer) {\n const index = parentPixiContainer.getChildIndex(this._pixiContainer);\n parentPixiContainer.addChildAt(this._lightingSprite, index);\n parentPixiContainer.removeChild(this._pixiContainer);\n }\n }\n }\n\n //Register the class to let the engine use it.\n export type LayerRenderer = gdjs.LayerPixiRenderer;\n export const LayerRenderer = gdjs.LayerPixiRenderer;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../GDevelop/GDJS/Runtime/pixi-renderers/loadingscreen-pixi-renderer.ts"],
|
|
4
|
-
"sourcesContent": ["namespace gdjs {\n enum LoadingScreenState {\n NOT_STARTED,\n STARTED,\n FINISHED,\n }\n\n const fadeIn = (\n object: { alpha: number } | null,\n duration: float,\n deltaTimeInMs: float\n ) => {\n if (!object) return;\n if (duration > 0) {\n object.alpha += ((1 / duration) * deltaTimeInMs) / 1000;\n if (object.alpha > 1) object.alpha = 1;\n } else {\n object.alpha = 1;\n }\n };\n const hasFadedIn = (object: PIXI.DisplayObject | null) => {\n return !object || object.alpha >= 1;\n };\n\n class LoadingScreenPixiRenderer {\n _pixiRenderer: PIXI.Renderer | null;\n _loadingScreenData: LoadingScreenData;\n _isFirstLayout: boolean;\n\n _loadingScreenContainer: PIXI.Container;\n _backgroundSprite: PIXI.Sprite | null = null;\n _gdevelopLogoSprite: PIXI.Sprite | null = null;\n _progressBarGraphics: PIXI.Graphics | null = null;\n\n _state: LoadingScreenState = LoadingScreenState.NOT_STARTED;\n _startTimeInMs: float = 0;\n _backgroundReadyTimeInMs: float = 0;\n _lastFrameTimeInMs: float = 0;\n _progressPercent: float = 0;\n\n private _isWatermarkEnabled: boolean;\n\n constructor(\n runtimeGamePixiRenderer: gdjs.RuntimeGamePixiRenderer,\n imageManager: gdjs.PixiImageManager,\n loadingScreenData: LoadingScreenData,\n isWatermarkEnabled: boolean,\n isFirstScene: boolean\n ) {\n this._loadingScreenData = loadingScreenData;\n this._isWatermarkEnabled = isWatermarkEnabled;\n this._isFirstLayout = isFirstScene;\n this._loadingScreenContainer = new PIXI.Container();\n this._pixiRenderer = runtimeGamePixiRenderer.getPIXIRenderer();\n if (!this._pixiRenderer) {\n // A PIXI Renderer can be missing during tests, when creating a runtime game\n // without a canvas.\n return;\n }\n\n const backgroundTexture = imageManager.getOrLoadPIXITexture(\n loadingScreenData.backgroundImageResourceName\n );\n if (backgroundTexture !== imageManager.getInvalidPIXITexture()) {\n this._backgroundSprite = PIXI.Sprite.from(backgroundTexture);\n this._backgroundSprite.alpha = 0;\n this._backgroundSprite.anchor.x = 0.5;\n this._backgroundSprite.anchor.y = 0.5;\n this._loadingScreenContainer.addChild(this._backgroundSprite);\n }\n\n if (loadingScreenData.showGDevelopSplash && isFirstScene) {\n this._gdevelopLogoSprite = PIXI.Sprite.from(gdjs.gdevelopLogo);\n this._gdevelopLogoSprite.alpha = 0;\n this._gdevelopLogoSprite.anchor.x = 0.5;\n this._gdevelopLogoSprite.anchor.y = 0.5;\n this._loadingScreenContainer.addChild(this._gdevelopLogoSprite);\n }\n if (loadingScreenData.showProgressBar) {\n this._progressBarGraphics = new PIXI.Graphics();\n this._progressBarGraphics.alpha = 0;\n this._loadingScreenContainer.addChild(this._progressBarGraphics);\n }\n\n this._render(performance.now());\n }\n\n setPercent(percent: number) {\n this._progressPercent = percent;\n }\n\n private _startLoadingScreen() {\n if (!this._pixiRenderer) return;\n this._state = LoadingScreenState.STARTED;\n this._startTimeInMs = performance.now();\n }\n\n private _updatePositions() {\n if (!this._pixiRenderer) return;\n\n if (this._backgroundSprite && this._backgroundSprite.texture.valid) {\n this._backgroundSprite.position.x = this._pixiRenderer.width / 2;\n this._backgroundSprite.position.y = this._pixiRenderer.height / 2;\n const scale = Math.max(\n this._pixiRenderer.width / this._backgroundSprite.texture.width,\n this._pixiRenderer.height / this._backgroundSprite.texture.height\n );\n this._backgroundSprite.scale.x = scale;\n this._backgroundSprite.scale.y = scale;\n }\n\n if (this._gdevelopLogoSprite) {\n this._gdevelopLogoSprite.position.x = this._pixiRenderer.width / 2;\n this._gdevelopLogoSprite.position.y = this._pixiRenderer.height / 2;\n const logoWidth = 680;\n const border =\n this._pixiRenderer.width > this._pixiRenderer.height &&\n this._pixiRenderer.width > 500\n ? 150\n : 35;\n const desiredWidth = Math.min(\n logoWidth,\n Math.max(1, this._pixiRenderer.width - border * 2)\n );\n const scale = desiredWidth / logoWidth;\n this._gdevelopLogoSprite.scale.x = scale;\n this._gdevelopLogoSprite.scale.y = scale;\n\n // Give up trying to show the logo if the resolution is really too small.\n // TODO: use a low resolution logo instead.\n this._gdevelopLogoSprite.visible =\n this._pixiRenderer.width > 200 && this._pixiRenderer.height > 200;\n }\n }\n\n private _render(timeInMs: float) {\n if (!this._pixiRenderer) {\n return;\n }\n\n // Continue the rendering loop as long as the loading screen is not finished.\n if (this._state !== LoadingScreenState.FINISHED) {\n requestAnimationFrame(() => this._render(performance.now()));\n this._renderIfNeeded(timeInMs);\n }\n }\n\n renderIfNeeded(): boolean {\n return this._renderIfNeeded(performance.now());\n }\n\n private _renderIfNeeded(timeInMs: float): boolean {\n if (timeInMs - this._lastFrameTimeInMs < 1000 / 60) {\n return false;\n }\n\n if (!this._pixiRenderer) {\n return false;\n }\n\n const deltaTimeInMs = this._lastFrameTimeInMs\n ? timeInMs - this._lastFrameTimeInMs\n : 0;\n this._lastFrameTimeInMs = timeInMs;\n\n this._updatePositions();\n\n if (this._state === LoadingScreenState.FINISHED) {\n return true;\n }\n if (this._state == LoadingScreenState.NOT_STARTED) {\n this._pixiRenderer.background.color = this._loadingScreenData.backgroundColor;\n if (!this._backgroundSprite || this._backgroundSprite.texture.valid) {\n this._startLoadingScreen();\n }\n return true;\n }\n\n const backgroundFadeInDuration = this._loadingScreenData\n .backgroundFadeInDuration;\n\n if (!this._backgroundSprite) {\n fadeIn(\n this._pixiRenderer.background,\n backgroundFadeInDuration,\n deltaTimeInMs\n );\n }\n this._pixiRenderer.clear();\n fadeIn(this._backgroundSprite, backgroundFadeInDuration, deltaTimeInMs);\n\n if (hasFadedIn(this._backgroundSprite)) {\n if (!this._backgroundReadyTimeInMs)\n this._backgroundReadyTimeInMs = timeInMs;\n\n const logoAndProgressFadeInDuration = this._loadingScreenData\n .logoAndProgressFadeInDuration;\n const logoAndProgressLogoFadeInDelay = this._loadingScreenData\n .logoAndProgressLogoFadeInDelay;\n\n if (\n timeInMs - this._backgroundReadyTimeInMs >\n logoAndProgressLogoFadeInDelay * 1000\n ) {\n fadeIn(\n this._gdevelopLogoSprite,\n logoAndProgressFadeInDuration,\n deltaTimeInMs\n );\n fadeIn(\n this._progressBarGraphics,\n logoAndProgressFadeInDuration,\n deltaTimeInMs\n );\n }\n }\n\n if (this._progressBarGraphics) {\n const color = this._loadingScreenData.progressBarColor;\n let progressBarWidth =\n (this._loadingScreenData.progressBarWidthPercent / 100) *\n this._pixiRenderer.width;\n if (this._loadingScreenData.progressBarMaxWidth > 0) {\n if (progressBarWidth > this._loadingScreenData.progressBarMaxWidth)\n progressBarWidth = this._loadingScreenData.progressBarMaxWidth;\n }\n if (this._loadingScreenData.progressBarMinWidth > 0) {\n if (progressBarWidth < this._loadingScreenData.progressBarMinWidth)\n progressBarWidth = this._loadingScreenData.progressBarMinWidth;\n }\n\n const progressBarHeight = this._loadingScreenData.progressBarHeight;\n const progressBarX = Math.floor(\n this._pixiRenderer.width / 2 - progressBarWidth / 2\n );\n const progressBarY =\n this._pixiRenderer.height < 350\n ? Math.floor(this._pixiRenderer.height - 10 - progressBarHeight)\n : Math.floor(this._pixiRenderer.height - 90 - progressBarHeight);\n const lineWidth = 1;\n // Display bar with an additional 1% to ensure it's filled at the end.\n const progress = Math.min(1, (this._progressPercent + 1) / 100);\n this._progressBarGraphics.clear();\n this._progressBarGraphics.lineStyle(lineWidth, color, 1, 0);\n this._progressBarGraphics.drawRect(\n progressBarX,\n progressBarY,\n progressBarWidth,\n progressBarHeight\n );\n\n this._progressBarGraphics.beginFill(color, 1);\n this._progressBarGraphics.lineStyle(0, color, 1);\n this._progressBarGraphics.drawRect(\n progressBarX + lineWidth,\n progressBarY + lineWidth,\n progressBarWidth * progress - lineWidth * 2,\n progressBarHeight - lineWidth * 2\n );\n this._progressBarGraphics.endFill();\n }\n\n this._pixiRenderer.render(this._loadingScreenContainer);\n return true;\n }\n\n unload(): Promise<void> {\n const totalElapsedTime = (performance.now() - this._startTimeInMs) / 1000;\n\n /**\n * The duration before something bright may appear on screen at 100%\n * opacity.\n */\n const fadeInDuration = Math.min(\n this._loadingScreenData.showGDevelopSplash\n ? this._loadingScreenData.logoAndProgressLogoFadeInDelay +\n this._loadingScreenData.logoAndProgressFadeInDuration\n : Number.POSITIVE_INFINITY,\n this._loadingScreenData.backgroundImageResourceName ||\n this._loadingScreenData.backgroundColor\n ? this._loadingScreenData.backgroundFadeInDuration\n : Number.POSITIVE_INFINITY\n );\n\n if (\n // Intermediate loading screens can be skipped as soon as possible.\n !this._isFirstLayout ||\n // Skip the 1st loading screen if nothing is too much visible yet to\n // avoid flashing users eyes.\n // This will likely only happen when the game is played a 2nd time\n // and resources are already in cache.\n (this._isWatermarkEnabled && totalElapsedTime < fadeInDuration / 2) ||\n // Otherwise, display the loading screen at least the minimal duration\n // set in game settings.\n totalElapsedTime > this._loadingScreenData.minDuration\n ) {\n this._state = LoadingScreenState.FINISHED;\n return Promise.resolve();\n }\n const remainingTime =\n this._loadingScreenData.minDuration - totalElapsedTime;\n this.setPercent(100);\n return new Promise((resolve) =>\n setTimeout(() => {\n this._state = LoadingScreenState.FINISHED;\n resolve();\n }, remainingTime * 1000)\n );\n }\n }\n\n //Register the class to let the engine use it.\n export const LoadingScreenRenderer = LoadingScreenPixiRenderer;\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["namespace gdjs {\n enum LoadingScreenState {\n NOT_STARTED,\n STARTED,\n FINISHED,\n }\n\n const fadeIn = (\n object: { alpha: number } | null,\n duration: float,\n deltaTimeInMs: float\n ) => {\n if (!object) return;\n if (duration > 0) {\n object.alpha += ((1 / duration) * deltaTimeInMs) / 1000;\n if (object.alpha > 1) object.alpha = 1;\n } else {\n object.alpha = 1;\n }\n };\n const hasFadedIn = (object: PIXI.DisplayObject | null) => {\n return !object || object.alpha >= 1;\n };\n\n class LoadingScreenPixiRenderer {\n _pixiRenderer: PIXI.Renderer | null;\n _loadingScreenData: LoadingScreenData;\n _isFirstLayout: boolean;\n\n _loadingScreenContainer: PIXI.Container;\n _backgroundSprite: PIXI.Sprite | null = null;\n _gdevelopLogoSprite: PIXI.Sprite | null = null;\n _progressBarGraphics: PIXI.Graphics | null = null;\n\n _state: LoadingScreenState = LoadingScreenState.NOT_STARTED;\n _startTimeInMs: float = 0;\n _backgroundReadyTimeInMs: float = 0;\n _lastFrameTimeInMs: float = 0;\n _progressPercent: float = 0;\n\n private _isWatermarkEnabled: boolean;\n\n constructor(\n runtimeGamePixiRenderer: gdjs.RuntimeGamePixiRenderer,\n imageManager: gdjs.PixiImageManager,\n loadingScreenData: LoadingScreenData,\n isWatermarkEnabled: boolean,\n isFirstScene: boolean\n ) {\n this._loadingScreenData = loadingScreenData;\n this._isWatermarkEnabled = isWatermarkEnabled;\n this._isFirstLayout = isFirstScene;\n this._loadingScreenContainer = new PIXI.Container();\n this._pixiRenderer = runtimeGamePixiRenderer.getPIXIRenderer();\n if (!this._pixiRenderer) {\n // A PIXI Renderer can be missing during tests, when creating a runtime game\n // without a canvas.\n return;\n }\n\n const backgroundTexture = imageManager.getOrLoadPIXITexture(\n loadingScreenData.backgroundImageResourceName\n );\n if (backgroundTexture !== imageManager.getInvalidPIXITexture()) {\n this._backgroundSprite = PIXI.Sprite.from(backgroundTexture);\n this._backgroundSprite.alpha = 0;\n this._backgroundSprite.anchor.x = 0.5;\n this._backgroundSprite.anchor.y = 0.5;\n this._loadingScreenContainer.addChild(this._backgroundSprite);\n }\n\n if (loadingScreenData.showGDevelopSplash && isFirstScene) {\n this._gdevelopLogoSprite = PIXI.Sprite.from(gdjs.gdevelopLogo);\n this._gdevelopLogoSprite.alpha = 0;\n this._gdevelopLogoSprite.anchor.x = 0.5;\n this._gdevelopLogoSprite.anchor.y = 0.5;\n this._loadingScreenContainer.addChild(this._gdevelopLogoSprite);\n }\n if (loadingScreenData.showProgressBar) {\n this._progressBarGraphics = new PIXI.Graphics();\n this._progressBarGraphics.alpha = 0;\n this._loadingScreenContainer.addChild(this._progressBarGraphics);\n }\n\n this._render(performance.now());\n }\n\n setPercent(percent: number) {\n this._progressPercent = percent;\n }\n\n private _startLoadingScreen() {\n if (!this._pixiRenderer) return;\n this._state = LoadingScreenState.STARTED;\n this._startTimeInMs = performance.now();\n }\n\n private _updatePositions() {\n if (!this._pixiRenderer) return;\n\n if (this._backgroundSprite && this._backgroundSprite.texture.valid) {\n this._backgroundSprite.position.x = this._pixiRenderer.width / 2;\n this._backgroundSprite.position.y = this._pixiRenderer.height / 2;\n const scale = Math.max(\n this._pixiRenderer.width / this._backgroundSprite.texture.width,\n this._pixiRenderer.height / this._backgroundSprite.texture.height\n );\n this._backgroundSprite.scale.x = scale;\n this._backgroundSprite.scale.y = scale;\n }\n\n if (this._gdevelopLogoSprite) {\n this._gdevelopLogoSprite.position.x = this._pixiRenderer.width / 2;\n this._gdevelopLogoSprite.position.y = this._pixiRenderer.height / 2;\n const logoWidth = 680;\n const border =\n this._pixiRenderer.width > this._pixiRenderer.height &&\n this._pixiRenderer.width > 500\n ? 150\n : 35;\n const desiredWidth = Math.min(\n logoWidth,\n Math.max(1, this._pixiRenderer.width - border * 2)\n );\n const scale = desiredWidth / logoWidth;\n this._gdevelopLogoSprite.scale.x = scale;\n this._gdevelopLogoSprite.scale.y = scale;\n\n // Give up trying to show the logo if the resolution is really too small.\n // TODO: use a low resolution logo instead.\n this._gdevelopLogoSprite.visible =\n this._pixiRenderer.width > 200 && this._pixiRenderer.height > 200;\n }\n }\n\n private _render(timeInMs: float) {\n if (!this._pixiRenderer) {\n return;\n }\n\n // Continue the rendering loop as long as the loading screen is not finished.\n if (this._state !== LoadingScreenState.FINISHED) {\n requestAnimationFrame(() => this._render(performance.now()));\n this._renderIfNeeded(timeInMs);\n }\n }\n\n renderIfNeeded(): boolean {\n return this._renderIfNeeded(performance.now());\n }\n\n private _renderIfNeeded(timeInMs: float): boolean {\n if (timeInMs - this._lastFrameTimeInMs < 1000 / 60) {\n return false;\n }\n\n if (!this._pixiRenderer) {\n return false;\n }\n\n const deltaTimeInMs = this._lastFrameTimeInMs\n ? timeInMs - this._lastFrameTimeInMs\n : 0;\n this._lastFrameTimeInMs = timeInMs;\n\n this._updatePositions();\n\n if (this._state === LoadingScreenState.FINISHED) {\n return true;\n }\n if (this._state == LoadingScreenState.NOT_STARTED) {\n this._pixiRenderer.background.color =\n this._loadingScreenData.backgroundColor;\n if (!this._backgroundSprite || this._backgroundSprite.texture.valid) {\n this._startLoadingScreen();\n }\n return true;\n }\n\n const backgroundFadeInDuration =\n this._loadingScreenData.backgroundFadeInDuration;\n\n if (!this._backgroundSprite) {\n fadeIn(\n this._pixiRenderer.background,\n backgroundFadeInDuration,\n deltaTimeInMs\n );\n }\n this._pixiRenderer.clear();\n fadeIn(this._backgroundSprite, backgroundFadeInDuration, deltaTimeInMs);\n\n if (hasFadedIn(this._backgroundSprite)) {\n if (!this._backgroundReadyTimeInMs)\n this._backgroundReadyTimeInMs = timeInMs;\n\n const logoAndProgressFadeInDuration =\n this._loadingScreenData.logoAndProgressFadeInDuration;\n const logoAndProgressLogoFadeInDelay =\n this._loadingScreenData.logoAndProgressLogoFadeInDelay;\n\n if (\n timeInMs - this._backgroundReadyTimeInMs >\n logoAndProgressLogoFadeInDelay * 1000\n ) {\n fadeIn(\n this._gdevelopLogoSprite,\n logoAndProgressFadeInDuration,\n deltaTimeInMs\n );\n fadeIn(\n this._progressBarGraphics,\n logoAndProgressFadeInDuration,\n deltaTimeInMs\n );\n }\n }\n\n if (this._progressBarGraphics) {\n const color = this._loadingScreenData.progressBarColor;\n let progressBarWidth =\n (this._loadingScreenData.progressBarWidthPercent / 100) *\n this._pixiRenderer.width;\n if (this._loadingScreenData.progressBarMaxWidth > 0) {\n if (progressBarWidth > this._loadingScreenData.progressBarMaxWidth)\n progressBarWidth = this._loadingScreenData.progressBarMaxWidth;\n }\n if (this._loadingScreenData.progressBarMinWidth > 0) {\n if (progressBarWidth < this._loadingScreenData.progressBarMinWidth)\n progressBarWidth = this._loadingScreenData.progressBarMinWidth;\n }\n\n const progressBarHeight = this._loadingScreenData.progressBarHeight;\n const progressBarX = Math.floor(\n this._pixiRenderer.width / 2 - progressBarWidth / 2\n );\n const progressBarY =\n this._pixiRenderer.height < 350\n ? Math.floor(this._pixiRenderer.height - 10 - progressBarHeight)\n : Math.floor(this._pixiRenderer.height - 90 - progressBarHeight);\n const lineWidth = 1;\n // Display bar with an additional 1% to ensure it's filled at the end.\n const progress = Math.min(1, (this._progressPercent + 1) / 100);\n this._progressBarGraphics.clear();\n this._progressBarGraphics.lineStyle(lineWidth, color, 1, 0);\n this._progressBarGraphics.drawRect(\n progressBarX,\n progressBarY,\n progressBarWidth,\n progressBarHeight\n );\n\n this._progressBarGraphics.beginFill(color, 1);\n this._progressBarGraphics.lineStyle(0, color, 1);\n this._progressBarGraphics.drawRect(\n progressBarX + lineWidth,\n progressBarY + lineWidth,\n progressBarWidth * progress - lineWidth * 2,\n progressBarHeight - lineWidth * 2\n );\n this._progressBarGraphics.endFill();\n }\n\n this._pixiRenderer.render(this._loadingScreenContainer);\n return true;\n }\n\n unload(): Promise<void> {\n const totalElapsedTime = (performance.now() - this._startTimeInMs) / 1000;\n\n /**\n * The duration before something bright may appear on screen at 100%\n * opacity.\n */\n const fadeInDuration = Math.min(\n this._loadingScreenData.showGDevelopSplash\n ? this._loadingScreenData.logoAndProgressLogoFadeInDelay +\n this._loadingScreenData.logoAndProgressFadeInDuration\n : Number.POSITIVE_INFINITY,\n this._loadingScreenData.backgroundImageResourceName ||\n this._loadingScreenData.backgroundColor\n ? this._loadingScreenData.backgroundFadeInDuration\n : Number.POSITIVE_INFINITY\n );\n\n if (\n // Intermediate loading screens can be skipped as soon as possible.\n !this._isFirstLayout ||\n // Skip the 1st loading screen if nothing is too much visible yet to\n // avoid flashing users eyes.\n // This will likely only happen when the game is played a 2nd time\n // and resources are already in cache.\n (this._isWatermarkEnabled && totalElapsedTime < fadeInDuration / 2) ||\n // Otherwise, display the loading screen at least the minimal duration\n // set in game settings.\n totalElapsedTime > this._loadingScreenData.minDuration\n ) {\n this._state = LoadingScreenState.FINISHED;\n return Promise.resolve();\n }\n const remainingTime =\n this._loadingScreenData.minDuration - totalElapsedTime;\n this.setPercent(100);\n return new Promise((resolve) =>\n setTimeout(() => {\n this._state = LoadingScreenState.FINISHED;\n resolve();\n }, remainingTime * 1000)\n );\n }\n }\n\n //Register the class to let the engine use it.\n export const LoadingScreenRenderer = LoadingScreenPixiRenderer;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../GDevelop/GDJS/Runtime/pixi-renderers/pixi-bitmapfont-manager.ts"],
|
|
4
|
-
"sourcesContent": ["/*\n * GDevelop JS Platform\n * Copyright 2021-present Aur\u00E9lien Vivet (bouh.vivez@gmail.com). All rights reserved.\n * This project is released under the MIT License.\n */\nnamespace gdjs {\n const logger = new gdjs.Logger('Bitmap text');\n\n const defaultBitmapFontKey = 'GDJS-DEFAULT-BITMAP-FONT';\n\n // When a font is unused, we put it in a cache of unused fonts. It's unloaded\n // from memory only when the cache is full and the font is at the last position\n // in the cache.\n // Set this to 0 to unload from memory (\"uninstall\") as soon as a font is unused.\n const uninstallCacheSize = 5;\n\n /**\n * We patch the installed font to use a name that is unique for each font data and texture,\n * to avoid conflicts between different font files using the same font name (by default, the\n * font name used by Pixi is the one inside the font data, but this name is not necessarily unique.\n * For example, 2 resources can use the same font, or we can have multiple objects with the same\n * font data and different textures).\n */\n const patchInstalledBitmapFont = (\n bitmapFont: PIXI.BitmapFont,\n bitmapFontInstallKey: string\n ) => {\n const defaultName = bitmapFont.font;\n // @ts-ignore - we \"hack\" into Pixi to change the font name\n bitmapFont.font = bitmapFontInstallKey;\n PIXI.BitmapFont.available[bitmapFontInstallKey] = bitmapFont;\n delete PIXI.BitmapFont.available[defaultName];\n return PIXI.BitmapFont.available[bitmapFontInstallKey];\n };\n\n const resourceKinds: Array<ResourceKind> = ['bitmapFont'];\n\n /**\n * PixiBitmapFontManager loads fnt/xml files (using `fetch`), from the \"bitmapFont\" resources of the game.\n *\n * It installs the \"BitmapFont\" with PixiJS to be used with PIXI.BitmapText.\n */\n export class PixiBitmapFontManager implements gdjs.ResourceManager {\n private _imageManager: gdjs.PixiImageManager;\n\n /** Pixi.BitmapFont used, indexed by their BitmapFont name. */\n private _pixiBitmapFontsInUse: Record<\n string,\n { objectsUsingTheFont: number }\n > = {};\n\n /** Pixi.BitmapFont not used anymore, but not yet uninstalled, indexed by their BitmapFont name. */\n private _pixiBitmapFontsToUninstall: string[] = [];\n\n /** Loaded fonts data, indexed by resource name. */\n private _loadedFontsData = new gdjs.ResourceCache<any>();\n\n private _defaultSlugFontName: string | null = null;\n\n _resourceLoader: gdjs.ResourceLoader;\n\n /**\n * @param resourceDataArray The resources data of the game.\n * @param resourceLoader The resources loader of the game.\n * @param imageManager The image manager to be used to get textures used by fonts.\n */\n constructor(\n resourceLoader: gdjs.ResourceLoader,\n imageManager: gdjs.PixiImageManager\n ) {\n this._imageManager = imageManager;\n this._resourceLoader = resourceLoader;\n }\n\n getResourceKinds(): ResourceKind[] {\n return resourceKinds;\n }\n\n /**\n * Get the instance of the default `Pixi.BitmapFont`, always available.\n */\n getDefaultBitmapFont() {\n if (this._defaultSlugFontName !== null) {\n return PIXI.BitmapFont.available[this._defaultSlugFontName];\n }\n\n // Default bitmap font style\n const fontFamily = 'Arial';\n const bitmapFontStyle = new PIXI.TextStyle({\n fontFamily: fontFamily,\n fontSize: 20,\n padding: 5,\n align: 'left',\n fill: '#ffffff',\n wordWrap: true,\n lineHeight: 20,\n });\n\n // Generate default bitmapFont, and replace the name of PIXI.BitmapFont by a unique name\n const defaultBitmapFont = patchInstalledBitmapFont(\n PIXI.BitmapFont.from(fontFamily, bitmapFontStyle, {\n // All the printable ASCII characters\n chars: [[' ', '~']],\n }),\n defaultBitmapFontKey\n );\n\n // Define the default name used for the default bitmap font.\n this._defaultSlugFontName = defaultBitmapFont.font;\n return defaultBitmapFont;\n }\n\n /**\n * Called to specify that the bitmap font with the specified key is used by an object\n * (i.e: this is reference counting).\n * `releaseBitmapFont` *must* be called to mark the font as not used anymore when the\n * object is destroyed or its font changed.\n *\n * @param bitmapFontInstallKey Name of the font of the BitmapFont (`bitmapFont.font`)\n */\n private _markBitmapFontAsUsed(bitmapFontInstallKey: string): void {\n this._pixiBitmapFontsInUse[bitmapFontInstallKey] = this\n ._pixiBitmapFontsInUse[bitmapFontInstallKey] || {\n objectsUsingTheFont: 0,\n };\n this._pixiBitmapFontsInUse[bitmapFontInstallKey].objectsUsingTheFont++;\n\n for (let i = 0; i < this._pixiBitmapFontsToUninstall.length; ) {\n if (this._pixiBitmapFontsToUninstall[i] === bitmapFontInstallKey) {\n // The font is in the cache of fonts to uninstall, because it was previously used and then marked as not used anymore.\n // Remove it from the cache to avoid the font getting uninstalled.\n this._pixiBitmapFontsToUninstall.splice(i, 1);\n } else {\n i++;\n }\n }\n }\n\n /**\n * When a font is not used by an object anymore (object destroyed or font changed),\n * call this function to decrease the internal count of objects using the font.\n *\n * When a font is not unused anymore, it goes in a temporary cache. The cache holds up to 10 fonts.\n * If the cache reaches its maximum capacity, the oldest font is uninstalled from memory.\n *\n * @param bitmapFontInstallKey Name of the font of the BitmapFont (`bitmapFont.font`)\n */\n releaseBitmapFont(bitmapFontInstallKey: string) {\n if (bitmapFontInstallKey === defaultBitmapFontKey) {\n // Never uninstall the default font.\n return;\n }\n\n if (!this._pixiBitmapFontsInUse[bitmapFontInstallKey]) {\n logger.warn(\n 'BitmapFont with name ' +\n bitmapFontInstallKey +\n ' was tried to be released but was never marked as used.'\n );\n return;\n }\n this._pixiBitmapFontsInUse[bitmapFontInstallKey].objectsUsingTheFont--;\n\n if (\n this._pixiBitmapFontsInUse[bitmapFontInstallKey].objectsUsingTheFont ===\n 0\n ) {\n delete this._pixiBitmapFontsInUse[bitmapFontInstallKey];\n\n // Add the font name at the last position of the cache.\n if (!this._pixiBitmapFontsToUninstall.includes(bitmapFontInstallKey)) {\n this._pixiBitmapFontsToUninstall.push(bitmapFontInstallKey);\n }\n if (this._pixiBitmapFontsToUninstall.length > uninstallCacheSize) {\n // Remove the first font (i.e: the oldest one)\n const oldestUnloadedPixiBitmapFontName = this._pixiBitmapFontsToUninstall.shift() as string;\n\n PIXI.BitmapFont.uninstall(oldestUnloadedPixiBitmapFontName);\n logger.log(\n 'Bitmap Text',\n 'Uninstalled BitmapFont \"' +\n oldestUnloadedPixiBitmapFontName +\n '\" from memory.'\n );\n }\n }\n }\n\n /**\n * Given a bitmap font resource name and a texture atlas resource name, returns the PIXI.BitmapFont\n * for it.\n * The font is register and should be released with `releaseBitmapFont` - so that it can be removed\n * from memory when unused.\n */\n obtainBitmapFont(\n bitmapFontResourceName: string,\n textureAtlasResourceName: string\n ): PIXI.BitmapFont {\n const bitmapFontInstallKey =\n bitmapFontResourceName + '@' + textureAtlasResourceName;\n\n if (PIXI.BitmapFont.available[bitmapFontInstallKey]) {\n // Return the existing BitmapFont that is already in memory and already installed.\n this._markBitmapFontAsUsed(bitmapFontInstallKey);\n return PIXI.BitmapFont.available[bitmapFontInstallKey];\n }\n\n // The Bitmap Font is not loaded, load it in memory.\n\n // First get the font data:\n const fontData = this._loadedFontsData.getFromName(\n bitmapFontResourceName\n );\n if (!fontData) {\n logger.warn(\n 'Could not find Bitmap Font for resource named \"' +\n bitmapFontResourceName +\n '\". The default font will be used.'\n );\n return this.getDefaultBitmapFont();\n }\n\n // Get the texture to be used in the font:\n const texture = this._imageManager.getPIXITexture(\n textureAtlasResourceName\n );\n\n try {\n // Create and install the Pixi.BitmapFont in memory:\n const bitmapFont = patchInstalledBitmapFont(\n PIXI.BitmapFont.install(fontData, texture),\n bitmapFontInstallKey\n );\n this._markBitmapFontAsUsed(bitmapFontInstallKey);\n return bitmapFont;\n } catch (error) {\n logger.error(\n 'Could not load the Bitmap Font for resource named \"' +\n bitmapFontResourceName +\n '\". The default font will be used. Error is: ' +\n error\n );\n return this.getDefaultBitmapFont();\n }\n }\n\n async processResource(resourceName: string): Promise<void> {\n // Do nothing because fonts are light enough to be parsed in background.\n }\n\n /**\n * Load the \"bitmapFont\" resources of the game, so that they are ready\n * to be used when `obtainBitmapFont` is called.\n */\n async loadResource(resourceName: string): Promise<void> {\n const resource = this._resourceLoader.getResource(resourceName);\n if (!resource) {\n logger.warn(\n 'Unable to find bitmap font for resource \"' + resourceName + '\".'\n );\n return;\n }\n if (this._loadedFontsData.get(resource)) {\n return;\n }\n\n try {\n const response = await fetch(\n this._resourceLoader.getFullUrl(resource.file),\n {\n credentials: this._resourceLoader.checkIfCredentialsRequired(\n resource.file\n )\n ? // Any resource stored on the GDevelop Cloud buckets needs the \"credentials\" of the user,\n // i.e: its gdevelop.io cookie, to be passed.\n 'include'\n : // For other resources, use \"same-origin\" as done by default by fetch.\n 'same-origin',\n }\n );\n const fontData = await response.text();\n this._loadedFontsData.set(resource, fontData);\n } catch (error) {\n logger.error(\n \"Can't fetch the bitmap font file \" +\n resource.file +\n ', error: ' +\n error\n );\n }\n }\n\n /**\n * To be called when the game is disposed.\n * Uninstall all the fonts from memory and clear cache of loaded fonts.\n */\n dispose(): void {\n for (const bitmapFontInstallKey in this._pixiBitmapFontsInUse) {\n PIXI.BitmapFont.uninstall(bitmapFontInstallKey);\n }\n\n for (const bitmapFontInstallKey of this._pixiBitmapFontsToUninstall) {\n PIXI.BitmapFont.uninstall(bitmapFontInstallKey);\n }\n\n this._pixiBitmapFontsInUse = {};\n this._pixiBitmapFontsToUninstall.length = 0;\n this._loadedFontsData.clear();\n }\n }\n\n // Register the class to let the engine use it.\n export const BitmapFontManager = gdjs.PixiBitmapFontManager;\n export type BitmapFontManager = gdjs.PixiBitmapFontManager;\n}\n"],
|
|
5
|
-
"mappings": "AAKA,GAAU,MAAV,UAAU,EAAV,CACE,KAAM,GAAS,GAAI,GAAK,OAAO,eAEzB,EAAuB,2BAMvB,EAAqB,EASrB,EAA2B,CAC/B,EACA,IACG,CACH,KAAM,GAAc,EAAW,KAE/B,SAAW,KAAO,EAClB,KAAK,WAAW,UAAU,GAAwB,EAClD,MAAO,MAAK,WAAW,UAAU,GAC1B,KAAK,WAAW,UAAU,IAG7B,EAAqC,CAAC,cAOrC,OAA4D,
|
|
4
|
+
"sourcesContent": ["/*\n * GDevelop JS Platform\n * Copyright 2021-present Aur\u00E9lien Vivet (bouh.vivez@gmail.com). All rights reserved.\n * This project is released under the MIT License.\n */\nnamespace gdjs {\n const logger = new gdjs.Logger('Bitmap text');\n\n const defaultBitmapFontKey = 'GDJS-DEFAULT-BITMAP-FONT';\n\n // When a font is unused, we put it in a cache of unused fonts. It's unloaded\n // from memory only when the cache is full and the font is at the last position\n // in the cache.\n // Set this to 0 to unload from memory (\"uninstall\") as soon as a font is unused.\n const uninstallCacheSize = 5;\n\n /**\n * We patch the installed font to use a name that is unique for each font data and texture,\n * to avoid conflicts between different font files using the same font name (by default, the\n * font name used by Pixi is the one inside the font data, but this name is not necessarily unique.\n * For example, 2 resources can use the same font, or we can have multiple objects with the same\n * font data and different textures).\n */\n const patchInstalledBitmapFont = (\n bitmapFont: PIXI.BitmapFont,\n bitmapFontInstallKey: string\n ) => {\n const defaultName = bitmapFont.font;\n // @ts-ignore - we \"hack\" into Pixi to change the font name\n bitmapFont.font = bitmapFontInstallKey;\n PIXI.BitmapFont.available[bitmapFontInstallKey] = bitmapFont;\n delete PIXI.BitmapFont.available[defaultName];\n return PIXI.BitmapFont.available[bitmapFontInstallKey];\n };\n\n const resourceKinds: Array<ResourceKind> = ['bitmapFont'];\n\n /**\n * PixiBitmapFontManager loads fnt/xml files (using `fetch`), from the \"bitmapFont\" resources of the game.\n *\n * It installs the \"BitmapFont\" with PixiJS to be used with PIXI.BitmapText.\n */\n export class PixiBitmapFontManager implements gdjs.ResourceManager {\n private _imageManager: gdjs.PixiImageManager;\n\n /** Pixi.BitmapFont used, indexed by their BitmapFont name. */\n private _pixiBitmapFontsInUse: Record<\n string,\n { objectsUsingTheFont: number }\n > = {};\n\n /** Pixi.BitmapFont not used anymore, but not yet uninstalled, indexed by their BitmapFont name. */\n private _pixiBitmapFontsToUninstall: string[] = [];\n\n /** Loaded fonts data, indexed by resource name. */\n private _loadedFontsData = new gdjs.ResourceCache<any>();\n\n private _defaultSlugFontName: string | null = null;\n\n _resourceLoader: gdjs.ResourceLoader;\n\n /**\n * @param resourceLoader The resources loader of the game.\n * @param imageManager The image manager to be used to get textures used by fonts.\n */\n constructor(\n resourceLoader: gdjs.ResourceLoader,\n imageManager: gdjs.PixiImageManager\n ) {\n this._imageManager = imageManager;\n this._resourceLoader = resourceLoader;\n }\n\n getResourceKinds(): ResourceKind[] {\n return resourceKinds;\n }\n\n /**\n * Get the instance of the default `Pixi.BitmapFont`, always available.\n */\n getDefaultBitmapFont() {\n if (this._defaultSlugFontName !== null) {\n return PIXI.BitmapFont.available[this._defaultSlugFontName];\n }\n\n // Default bitmap font style\n const fontFamily = 'Arial';\n const bitmapFontStyle = new PIXI.TextStyle({\n fontFamily: fontFamily,\n fontSize: 20,\n padding: 5,\n align: 'left',\n fill: '#ffffff',\n wordWrap: true,\n lineHeight: 20,\n });\n\n // Generate default bitmapFont, and replace the name of PIXI.BitmapFont by a unique name\n const defaultBitmapFont = patchInstalledBitmapFont(\n PIXI.BitmapFont.from(fontFamily, bitmapFontStyle, {\n // All the printable ASCII characters\n chars: [[' ', '~']],\n }),\n defaultBitmapFontKey\n );\n\n // Define the default name used for the default bitmap font.\n this._defaultSlugFontName = defaultBitmapFont.font;\n return defaultBitmapFont;\n }\n\n /**\n * Called to specify that the bitmap font with the specified key is used by an object\n * (i.e: this is reference counting).\n * `releaseBitmapFont` *must* be called to mark the font as not used anymore when the\n * object is destroyed or its font changed.\n *\n * @param bitmapFontInstallKey Name of the font of the BitmapFont (`bitmapFont.font`)\n */\n private _markBitmapFontAsUsed(bitmapFontInstallKey: string): void {\n this._pixiBitmapFontsInUse[bitmapFontInstallKey] = this\n ._pixiBitmapFontsInUse[bitmapFontInstallKey] || {\n objectsUsingTheFont: 0,\n };\n this._pixiBitmapFontsInUse[bitmapFontInstallKey].objectsUsingTheFont++;\n\n for (let i = 0; i < this._pixiBitmapFontsToUninstall.length; ) {\n if (this._pixiBitmapFontsToUninstall[i] === bitmapFontInstallKey) {\n // The font is in the cache of fonts to uninstall, because it was previously used and then marked as not used anymore.\n // Remove it from the cache to avoid the font getting uninstalled.\n this._pixiBitmapFontsToUninstall.splice(i, 1);\n } else {\n i++;\n }\n }\n }\n\n /**\n * When a font is not used by an object anymore (object destroyed or font changed),\n * call this function to decrease the internal count of objects using the font.\n *\n * When a font is not unused anymore, it goes in a temporary cache. The cache holds up to 10 fonts.\n * If the cache reaches its maximum capacity, the oldest font is uninstalled from memory.\n *\n * @param bitmapFontInstallKey Name of the font of the BitmapFont (`bitmapFont.font`)\n */\n releaseBitmapFont(bitmapFontInstallKey: string) {\n if (bitmapFontInstallKey === defaultBitmapFontKey) {\n // Never uninstall the default font.\n return;\n }\n\n if (!this._pixiBitmapFontsInUse[bitmapFontInstallKey]) {\n logger.warn(\n 'BitmapFont with name ' +\n bitmapFontInstallKey +\n ' was tried to be released but was never marked as used.'\n );\n return;\n }\n this._pixiBitmapFontsInUse[bitmapFontInstallKey].objectsUsingTheFont--;\n\n if (\n this._pixiBitmapFontsInUse[bitmapFontInstallKey].objectsUsingTheFont ===\n 0\n ) {\n delete this._pixiBitmapFontsInUse[bitmapFontInstallKey];\n\n // Add the font name at the last position of the cache.\n if (!this._pixiBitmapFontsToUninstall.includes(bitmapFontInstallKey)) {\n this._pixiBitmapFontsToUninstall.push(bitmapFontInstallKey);\n }\n if (this._pixiBitmapFontsToUninstall.length > uninstallCacheSize) {\n // Remove the first font (i.e: the oldest one)\n const oldestUnloadedPixiBitmapFontName =\n this._pixiBitmapFontsToUninstall.shift() as string;\n\n PIXI.BitmapFont.uninstall(oldestUnloadedPixiBitmapFontName);\n logger.log(\n 'Bitmap Text',\n 'Uninstalled BitmapFont \"' +\n oldestUnloadedPixiBitmapFontName +\n '\" from memory.'\n );\n }\n }\n }\n\n /**\n * Given a bitmap font resource name and a texture atlas resource name, returns the PIXI.BitmapFont\n * for it.\n * The font is register and should be released with `releaseBitmapFont` - so that it can be removed\n * from memory when unused.\n */\n obtainBitmapFont(\n bitmapFontResourceName: string,\n textureAtlasResourceName: string\n ): PIXI.BitmapFont {\n const bitmapFontInstallKey =\n bitmapFontResourceName + '@' + textureAtlasResourceName;\n\n if (PIXI.BitmapFont.available[bitmapFontInstallKey]) {\n // Return the existing BitmapFont that is already in memory and already installed.\n this._markBitmapFontAsUsed(bitmapFontInstallKey);\n return PIXI.BitmapFont.available[bitmapFontInstallKey];\n }\n\n // The Bitmap Font is not loaded, load it in memory.\n\n // First get the font data:\n const fontData = this._loadedFontsData.getFromName(\n bitmapFontResourceName\n );\n if (!fontData) {\n logger.warn(\n 'Could not find Bitmap Font for resource named \"' +\n bitmapFontResourceName +\n '\". The default font will be used.'\n );\n return this.getDefaultBitmapFont();\n }\n\n // Get the texture to be used in the font:\n const texture = this._imageManager.getPIXITexture(\n textureAtlasResourceName\n );\n\n try {\n // Create and install the Pixi.BitmapFont in memory:\n const bitmapFont = patchInstalledBitmapFont(\n PIXI.BitmapFont.install(fontData, texture),\n bitmapFontInstallKey\n );\n this._markBitmapFontAsUsed(bitmapFontInstallKey);\n return bitmapFont;\n } catch (error) {\n logger.error(\n 'Could not load the Bitmap Font for resource named \"' +\n bitmapFontResourceName +\n '\". The default font will be used. Error is: ' +\n error\n );\n return this.getDefaultBitmapFont();\n }\n }\n\n async processResource(resourceName: string): Promise<void> {\n // Do nothing because fonts are light enough to be parsed in background.\n }\n\n /**\n * Load the \"bitmapFont\" resources of the game, so that they are ready\n * to be used when `obtainBitmapFont` is called.\n */\n async loadResource(resourceName: string): Promise<void> {\n const resource = this._resourceLoader.getResource(resourceName);\n if (!resource) {\n logger.warn(\n 'Unable to find bitmap font for resource \"' + resourceName + '\".'\n );\n return;\n }\n if (this._loadedFontsData.get(resource)) {\n return;\n }\n\n try {\n const response = await fetch(\n this._resourceLoader.getFullUrl(resource.file),\n {\n credentials: this._resourceLoader.checkIfCredentialsRequired(\n resource.file\n )\n ? // Any resource stored on the GDevelop Cloud buckets needs the \"credentials\" of the user,\n // i.e: its gdevelop.io cookie, to be passed.\n 'include'\n : // For other resources, use \"same-origin\" as done by default by fetch.\n 'same-origin',\n }\n );\n const fontData = await response.text();\n this._loadedFontsData.set(resource, fontData);\n } catch (error) {\n logger.error(\n \"Can't fetch the bitmap font file \" +\n resource.file +\n ', error: ' +\n error\n );\n }\n }\n\n /**\n * To be called when the game is disposed.\n * Uninstall all the fonts from memory and clear cache of loaded fonts.\n */\n dispose(): void {\n for (const bitmapFontInstallKey in this._pixiBitmapFontsInUse) {\n PIXI.BitmapFont.uninstall(bitmapFontInstallKey);\n }\n\n for (const bitmapFontInstallKey of this._pixiBitmapFontsToUninstall) {\n PIXI.BitmapFont.uninstall(bitmapFontInstallKey);\n }\n\n this._pixiBitmapFontsInUse = {};\n this._pixiBitmapFontsToUninstall.length = 0;\n this._loadedFontsData.clear();\n }\n }\n\n // Register the class to let the engine use it.\n export const BitmapFontManager = gdjs.PixiBitmapFontManager;\n export type BitmapFontManager = gdjs.PixiBitmapFontManager;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../GDevelop/GDJS/Runtime/pixi-renderers/pixi-filters-tools.ts"],
|
|
4
|
-
"sourcesContent": ["namespace gdjs {\n const logger = new gdjs.Logger('Filters');\n\n export namespace PixiFiltersTools {\n export const clampValue = function (value, min, max) {\n return Math.max(min, Math.min(max, value));\n };\n\n export const clampKernelSize = function (value, min, max) {\n const len = Math.round((max - min) / 2 + 1);\n const arr = new Array(len);\n for (let i = 0; i < len; i++) {\n arr[i] = min + 2 * i;\n }\n return arr.indexOf(value) !== -1 ? value : min;\n };\n\n const _filterCreators: {\n [filterName: string]: FilterCreator;\n } = {};\n\n /**\n * Return the creator for the filter with the given name, if any.\n * @param filterName The name of the filter to get\n * @return The filter creator, if any (null otherwise).\n */\n export const getFilterCreator = function (\n filterName: string\n ): FilterCreator | null {\n if (_filterCreators.hasOwnProperty(filterName)) {\n return _filterCreators[filterName];\n }\n return null;\n };\n\n /**\n * Register a new PIXI filter creator, to be used by GDJS.\n * @param filterName The name of the filter to get\n * @param filterCreator The object used to create the filter.\n */\n export const registerFilterCreator = function (\n filterName: string,\n filterCreator: FilterCreator\n ) {\n if (_filterCreators.hasOwnProperty(filterName)) {\n logger.warn(\n 'Filter \"' +\n filterName +\n '\" was already registered in gdjs.PixiFiltersTools. Replacing it with the new one.'\n );\n }\n _filterCreators[filterName] = filterCreator;\n };\n\n /** A wrapper allowing to create an effect. */\n export interface FilterCreator {\n /** Function to call to create the filter */\n makeFilter(target: EffectsTarget, effectData: EffectData): Filter;\n }\n\n /** An effect. */\n export interface Filter {\n /**\n * Check if an effect is enabled.\n * @return true if the filter is enabled\n */\n isEnabled(target: EffectsTarget): boolean;\n /**\n * Enable an effect.\n * @param enabled Set to true to enable, false to disable\n */\n setEnabled(target: EffectsTarget, enabled: boolean): boolean;\n /**\n * Apply the effect on the PixiJS DisplayObject.\n * Called after the effect is initialized.\n * @param rendererObject The renderer object\n * @param effect The effect to be applied.\n */\n applyEffect(target: EffectsTarget): boolean;\n removeEffect(target: EffectsTarget): boolean;\n /** The function to be called to update the filter at every frame before the rendering. */\n updatePreRender(target: gdjs.EffectsTarget): any;\n /** The function to be called to update a parameter (with a number) */\n updateDoubleParameter(\n //filter: PIXI.Filter,\n parameterName: string,\n value: number\n ): void;\n /** The function to be called to update a parameter (with a string) */\n updateStringParameter(parameterName: string, value: string): void;\n /** The function to be called to update a parameter (with a boolean) */\n updateBooleanParameter(parameterName: string, value: boolean): void;\n updateColorParameter(parameterName: string, value: number): void;\n getDoubleParameter(parameterName: string): number;\n getColorParameter(parameterName: string): number;\n getNetworkSyncData(): any;\n updateFromNetworkSyncData(syncData: any): void;\n }\n\n /** A wrapper allowing to create a PIXI filter and update it using a common interface */\n export abstract class PixiFilterCreator implements FilterCreator {\n /** Function to call to create the filter */\n makeFilter(target: EffectsTarget, effectData: EffectData): Filter {\n const pixiFilter = this.makePIXIFilter(target, effectData);\n if (target.isLightingLayer && target.isLightingLayer()) {\n pixiFilter.blendMode = PIXI.BLEND_MODES.ADD;\n }\n return new PixiFilter(pixiFilter, this);\n }\n /** Function to call to create the filter */\n abstract makePIXIFilter(\n target: EffectsTarget,\n effectData: EffectData\n ): any;\n /** The function to be called to update the filter at every frame before the rendering. */\n abstract updatePreRender(\n filter: PIXI.Filter,\n target: gdjs.EffectsTarget\n ): any;\n /** The function to be called to update a parameter (with a number) */\n abstract updateDoubleParameter(\n filter: PIXI.Filter,\n parameterName: string,\n value: number\n ): void;\n /** The function to be called to update a parameter (with a string) */\n abstract updateStringParameter(\n filter: PIXI.Filter,\n parameterName: string,\n value: string\n ): void;\n /** The function to be called to update a parameter (with a boolean) */\n abstract updateBooleanParameter(\n filter: PIXI.Filter,\n parameterName: string,\n value: boolean\n ): void;\n abstract updateColorParameter(\n filter: PIXI.Filter,\n parameterName: string,\n value: number\n ): void;\n abstract getDoubleParameter(\n filter: PIXI.Filter,\n parameterName: string\n ): number;\n abstract getColorParameter(\n filter: PIXI.Filter,\n parameterName: string\n ): number;\n abstract getNetworkSyncData(filter: PIXI.Filter): any;\n abstract updateFromNetworkSyncData(\n filter: PIXI.Filter,\n syncData: any\n ): void;\n }\n\n /**An effect used to manipulate a Pixi filter. */\n export class PixiFilter implements Filter {\n /** The PIXI filter */\n pixiFilter: PIXI.Filter;\n filterCreator: gdjs.PixiFiltersTools.PixiFilterCreator;\n\n constructor(\n pixiFilter: PIXI.Filter,\n filterCreator: gdjs.PixiFiltersTools.PixiFilterCreator\n ) {\n this.pixiFilter = pixiFilter;\n this.filterCreator = filterCreator;\n }\n\n isEnabled(target: EffectsTarget): boolean {\n return this.pixiFilter.enabled;\n }\n\n setEnabled(target: EffectsTarget, enabled: boolean): boolean {\n return (this.pixiFilter.enabled = enabled);\n }\n\n applyEffect(target: EffectsTarget): boolean {\n const rendererObject = target.getRendererObject() as\n | PIXI.DisplayObject\n | null\n | undefined;\n if (!rendererObject) {\n return false;\n }\n rendererObject.filters = (rendererObject.filters || []).concat(\n this.pixiFilter\n );\n return true;\n }\n\n removeEffect(target: EffectsTarget): boolean {\n const rendererObject = target.getRendererObject() as\n | PIXI.DisplayObject\n | null\n | undefined;\n if (!rendererObject) {\n return false;\n }\n rendererObject.filters = (rendererObject.filters || []).filter(\n (pixiFilter) => pixiFilter !== this.pixiFilter\n );\n return true;\n }\n\n updatePreRender(target: gdjs.EffectsTarget): any {\n this.filterCreator.updatePreRender(this.pixiFilter, target);\n }\n\n updateDoubleParameter(parameterName: string, value: number): void {\n this.filterCreator.updateDoubleParameter(\n this.pixiFilter,\n parameterName,\n value\n );\n }\n\n updateStringParameter(parameterName: string, value: string): void {\n this.filterCreator.updateStringParameter(\n this.pixiFilter,\n parameterName,\n value\n );\n }\n\n updateBooleanParameter(parameterName: string, value: boolean): void {\n this.filterCreator.updateBooleanParameter(\n this.pixiFilter,\n parameterName,\n value\n );\n }\n\n updateColorParameter(parameterName: string, value: number): void {\n this.filterCreator.updateColorParameter(\n this.pixiFilter,\n parameterName,\n value\n );\n }\n\n getDoubleParameter(parameterName: string): number {\n return this.filterCreator.getDoubleParameter(\n this.pixiFilter,\n parameterName\n );\n }\n\n getColorParameter(parameterName: string): number {\n return this.filterCreator.getColorParameter(\n this.pixiFilter,\n parameterName\n );\n }\n\n getNetworkSyncData(): any {\n return {\n ena: this.pixiFilter.enabled,\n fc: this.filterCreator.getNetworkSyncData(this.pixiFilter),\n };\n }\n\n updateFromNetworkSyncData(syncData: any): void {\n this.pixiFilter.enabled = syncData.ena;\n this.filterCreator.updateFromNetworkSyncData(\n this.pixiFilter,\n syncData.fc\n );\n }\n }\n\n export class EmptyFilter implements Filter {\n isEnabled(target: EffectsTarget): boolean {\n return false;\n }\n setEnabled(target: EffectsTarget, enabled: boolean): boolean {\n return false;\n }\n applyEffect(target: EffectsTarget): boolean {\n return false;\n }\n removeEffect(target: EffectsTarget): boolean {\n return false;\n }\n updatePreRender(target: gdjs.EffectsTarget): any {}\n updateDoubleParameter(parameterName: string, value: number): void {}\n updateStringParameter(parameterName: string, value: string): void {}\n updateBooleanParameter(parameterName: string, value: boolean): void {}\n updateColorParameter(parameterName: string, value: number): void {}\n getDoubleParameter(parameterName: string): number {\n return 0;\n }\n getColorParameter(parameterName: string): number {\n return 0;\n }\n getNetworkSyncData(): any {\n return {};\n }\n updateFromNetworkSyncData(syncData: any): void {}\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "AAAA,GAAU,MAAV,UAAU,EAAV,CACE,KAAM,GAAS,GAAI,GAAK,OAAO,WAExB,GAAU,GAAV,UAAU,EAAV,CACE,AAAM,aAAa,SAAU,EAAO,EAAK,EAAK,CACnD,MAAO,MAAK,IAAI,EAAK,KAAK,IAAI,EAAK,KAGxB,kBAAkB,SAAU,EAAO,EAAK,EAAK,CACxD,KAAM,GAAM,KAAK,MAAO,GAAM,GAAO,EAAI,GACnC,EAAM,GAAI,OAAM,GACtB,OAAS,GAAI,EAAG,EAAI,EAAK,IACvB,EAAI,GAAK,EAAM,EAAI,EAErB,MAAO,GAAI,QAAQ,KAAW,GAAK,EAAQ,GAG7C,KAAM,GAEF,GAOG,AAAM,mBAAmB,SAC9B,EACsB,CACtB,MAAI,GAAgB,eAAe,GAC1B,EAAgB,GAElB,MAQI,wBAAwB,SACnC,EACA,EACA,CACA,AAAI,EAAgB,eAAe,IACjC,EAAO,KACL,WACE,EACA,qFAGN,EAAgB,GAAc,
|
|
4
|
+
"sourcesContent": ["namespace gdjs {\n const logger = new gdjs.Logger('Filters');\n\n export namespace PixiFiltersTools {\n export const clampValue = function (value, min, max) {\n return Math.max(min, Math.min(max, value));\n };\n\n export const clampKernelSize = function (value, min, max) {\n const len = Math.round((max - min) / 2 + 1);\n const arr = new Array(len);\n for (let i = 0; i < len; i++) {\n arr[i] = min + 2 * i;\n }\n return arr.indexOf(value) !== -1 ? value : min;\n };\n\n const _filterCreators: {\n [filterName: string]: FilterCreator;\n } = {};\n\n /**\n * Return the creator for the filter with the given name, if any.\n * @param filterName The name of the filter to get\n * @return The filter creator, if any (null otherwise).\n */\n export const getFilterCreator = function (\n filterName: string\n ): FilterCreator | null {\n if (_filterCreators.hasOwnProperty(filterName)) {\n return _filterCreators[filterName];\n }\n return null;\n };\n\n /**\n * Register a new PIXI filter creator, to be used by GDJS.\n * @param filterName The name of the filter to get\n * @param filterCreator The object used to create the filter.\n */\n export const registerFilterCreator = function (\n filterName: string,\n filterCreator: FilterCreator\n ) {\n if (_filterCreators.hasOwnProperty(filterName)) {\n logger.warn(\n 'Filter \"' +\n filterName +\n '\" was already registered in gdjs.PixiFiltersTools. Replacing it with the new one.'\n );\n }\n _filterCreators[filterName] = filterCreator;\n };\n\n /** A wrapper allowing to create an effect. */\n export interface FilterCreator {\n /** Function to call to create the filter */\n makeFilter(target: EffectsTarget, effectData: EffectData): Filter;\n }\n\n /** An effect. */\n export interface Filter {\n /**\n * Check if an effect is enabled.\n * @return true if the filter is enabled\n */\n isEnabled(target: EffectsTarget): boolean;\n /**\n * Enable an effect.\n * @param enabled Set to true to enable, false to disable\n */\n setEnabled(target: EffectsTarget, enabled: boolean): boolean;\n /**\n * Apply the effect on the PixiJS DisplayObject.\n * Called after the effect is initialized.\n */\n applyEffect(target: EffectsTarget): boolean;\n removeEffect(target: EffectsTarget): boolean;\n /** The function to be called to update the filter at every frame before the rendering. */\n updatePreRender(target: gdjs.EffectsTarget): any;\n /** The function to be called to update a parameter (with a number) */\n updateDoubleParameter(\n //filter: PIXI.Filter,\n parameterName: string,\n value: number\n ): void;\n /** The function to be called to update a parameter (with a string) */\n updateStringParameter(parameterName: string, value: string): void;\n /** The function to be called to update a parameter (with a boolean) */\n updateBooleanParameter(parameterName: string, value: boolean): void;\n updateColorParameter(parameterName: string, value: number): void;\n getDoubleParameter(parameterName: string): number;\n getColorParameter(parameterName: string): number;\n getNetworkSyncData(): any;\n updateFromNetworkSyncData(syncData: any): void;\n }\n\n /** A wrapper allowing to create a PIXI filter and update it using a common interface */\n export abstract class PixiFilterCreator implements FilterCreator {\n /** Function to call to create the filter */\n makeFilter(target: EffectsTarget, effectData: EffectData): Filter {\n const pixiFilter = this.makePIXIFilter(target, effectData);\n if (target.isLightingLayer && target.isLightingLayer()) {\n pixiFilter.blendMode = PIXI.BLEND_MODES.ADD;\n }\n return new PixiFilter(pixiFilter, this);\n }\n /** Function to call to create the filter */\n abstract makePIXIFilter(\n target: EffectsTarget,\n effectData: EffectData\n ): any;\n /** The function to be called to update the filter at every frame before the rendering. */\n abstract updatePreRender(\n filter: PIXI.Filter,\n target: gdjs.EffectsTarget\n ): any;\n /** The function to be called to update a parameter (with a number) */\n abstract updateDoubleParameter(\n filter: PIXI.Filter,\n parameterName: string,\n value: number\n ): void;\n /** The function to be called to update a parameter (with a string) */\n abstract updateStringParameter(\n filter: PIXI.Filter,\n parameterName: string,\n value: string\n ): void;\n /** The function to be called to update a parameter (with a boolean) */\n abstract updateBooleanParameter(\n filter: PIXI.Filter,\n parameterName: string,\n value: boolean\n ): void;\n abstract updateColorParameter(\n filter: PIXI.Filter,\n parameterName: string,\n value: number\n ): void;\n abstract getDoubleParameter(\n filter: PIXI.Filter,\n parameterName: string\n ): number;\n abstract getColorParameter(\n filter: PIXI.Filter,\n parameterName: string\n ): number;\n abstract getNetworkSyncData(filter: PIXI.Filter): any;\n abstract updateFromNetworkSyncData(\n filter: PIXI.Filter,\n syncData: any\n ): void;\n }\n\n /**An effect used to manipulate a Pixi filter. */\n export class PixiFilter implements Filter {\n /** The PIXI filter */\n pixiFilter: PIXI.Filter;\n filterCreator: gdjs.PixiFiltersTools.PixiFilterCreator;\n\n constructor(\n pixiFilter: PIXI.Filter,\n filterCreator: gdjs.PixiFiltersTools.PixiFilterCreator\n ) {\n this.pixiFilter = pixiFilter;\n this.filterCreator = filterCreator;\n }\n\n isEnabled(target: EffectsTarget): boolean {\n return this.pixiFilter.enabled;\n }\n\n setEnabled(target: EffectsTarget, enabled: boolean): boolean {\n return (this.pixiFilter.enabled = enabled);\n }\n\n applyEffect(target: EffectsTarget): boolean {\n const rendererObject = target.getRendererObject() as\n | PIXI.DisplayObject\n | null\n | undefined;\n if (!rendererObject) {\n return false;\n }\n rendererObject.filters = (rendererObject.filters || []).concat(\n this.pixiFilter\n );\n return true;\n }\n\n removeEffect(target: EffectsTarget): boolean {\n const rendererObject = target.getRendererObject() as\n | PIXI.DisplayObject\n | null\n | undefined;\n if (!rendererObject) {\n return false;\n }\n rendererObject.filters = (rendererObject.filters || []).filter(\n (pixiFilter) => pixiFilter !== this.pixiFilter\n );\n return true;\n }\n\n updatePreRender(target: gdjs.EffectsTarget): any {\n this.filterCreator.updatePreRender(this.pixiFilter, target);\n }\n\n updateDoubleParameter(parameterName: string, value: number): void {\n this.filterCreator.updateDoubleParameter(\n this.pixiFilter,\n parameterName,\n value\n );\n }\n\n updateStringParameter(parameterName: string, value: string): void {\n this.filterCreator.updateStringParameter(\n this.pixiFilter,\n parameterName,\n value\n );\n }\n\n updateBooleanParameter(parameterName: string, value: boolean): void {\n this.filterCreator.updateBooleanParameter(\n this.pixiFilter,\n parameterName,\n value\n );\n }\n\n updateColorParameter(parameterName: string, value: number): void {\n this.filterCreator.updateColorParameter(\n this.pixiFilter,\n parameterName,\n value\n );\n }\n\n getDoubleParameter(parameterName: string): number {\n return this.filterCreator.getDoubleParameter(\n this.pixiFilter,\n parameterName\n );\n }\n\n getColorParameter(parameterName: string): number {\n return this.filterCreator.getColorParameter(\n this.pixiFilter,\n parameterName\n );\n }\n\n getNetworkSyncData(): any {\n return {\n ena: this.pixiFilter.enabled,\n fc: this.filterCreator.getNetworkSyncData(this.pixiFilter),\n };\n }\n\n updateFromNetworkSyncData(syncData: any): void {\n this.pixiFilter.enabled = syncData.ena;\n this.filterCreator.updateFromNetworkSyncData(\n this.pixiFilter,\n syncData.fc\n );\n }\n }\n\n export class EmptyFilter implements Filter {\n isEnabled(target: EffectsTarget): boolean {\n return false;\n }\n setEnabled(target: EffectsTarget, enabled: boolean): boolean {\n return false;\n }\n applyEffect(target: EffectsTarget): boolean {\n return false;\n }\n removeEffect(target: EffectsTarget): boolean {\n return false;\n }\n updatePreRender(target: gdjs.EffectsTarget): any {}\n updateDoubleParameter(parameterName: string, value: number): void {}\n updateStringParameter(parameterName: string, value: string): void {}\n updateBooleanParameter(parameterName: string, value: boolean): void {}\n updateColorParameter(parameterName: string, value: number): void {}\n getDoubleParameter(parameterName: string): number {\n return 0;\n }\n getColorParameter(parameterName: string): number {\n return 0;\n }\n getNetworkSyncData(): any {\n return {};\n }\n updateFromNetworkSyncData(syncData: any): void {}\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,GAAU,MAAV,UAAU,EAAV,CACE,KAAM,GAAS,GAAI,GAAK,OAAO,WAExB,GAAU,GAAV,UAAU,EAAV,CACE,AAAM,aAAa,SAAU,EAAO,EAAK,EAAK,CACnD,MAAO,MAAK,IAAI,EAAK,KAAK,IAAI,EAAK,KAGxB,kBAAkB,SAAU,EAAO,EAAK,EAAK,CACxD,KAAM,GAAM,KAAK,MAAO,GAAM,GAAO,EAAI,GACnC,EAAM,GAAI,OAAM,GACtB,OAAS,GAAI,EAAG,EAAI,EAAK,IACvB,EAAI,GAAK,EAAM,EAAI,EAErB,MAAO,GAAI,QAAQ,KAAW,GAAK,EAAQ,GAG7C,KAAM,GAEF,GAOG,AAAM,mBAAmB,SAC9B,EACsB,CACtB,MAAI,GAAgB,eAAe,GAC1B,EAAgB,GAElB,MAQI,wBAAwB,SACnC,EACA,EACA,CACA,AAAI,EAAgB,eAAe,IACjC,EAAO,KACL,WACE,EACA,qFAGN,EAAgB,GAAc,GA+CzB,OAA0D,CAE/D,WAAW,EAAuB,EAAgC,CAChE,KAAM,GAAa,KAAK,eAAe,EAAQ,GAC/C,MAAI,GAAO,iBAAmB,EAAO,mBACnC,GAAW,UAAY,KAAK,YAAY,KAEnC,GAAI,GAAW,EAAY,OAP/B,EAAe,oBA0Df,OAAmC,CAKxC,YACE,EACA,EACA,CACA,KAAK,WAAa,EAClB,KAAK,cAAgB,EAGvB,UAAU,EAAgC,CACxC,MAAO,MAAK,WAAW,QAGzB,WAAW,EAAuB,EAA2B,CAC3D,MAAQ,MAAK,WAAW,QAAU,EAGpC,YAAY,EAAgC,CAC1C,KAAM,GAAiB,EAAO,oBAI9B,MAAK,GAGL,GAAe,QAAW,GAAe,SAAW,IAAI,OACtD,KAAK,YAEA,IALE,GAQX,aAAa,EAAgC,CAC3C,KAAM,GAAiB,EAAO,oBAI9B,MAAK,GAGL,GAAe,QAAW,GAAe,SAAW,IAAI,OACtD,AAAC,GAAe,IAAe,KAAK,YAE/B,IALE,GAQX,gBAAgB,EAAiC,CAC/C,KAAK,cAAc,gBAAgB,KAAK,WAAY,GAGtD,sBAAsB,EAAuB,EAAqB,CAChE,KAAK,cAAc,sBACjB,KAAK,WACL,EACA,GAIJ,sBAAsB,EAAuB,EAAqB,CAChE,KAAK,cAAc,sBACjB,KAAK,WACL,EACA,GAIJ,uBAAuB,EAAuB,EAAsB,CAClE,KAAK,cAAc,uBACjB,KAAK,WACL,EACA,GAIJ,qBAAqB,EAAuB,EAAqB,CAC/D,KAAK,cAAc,qBACjB,KAAK,WACL,EACA,GAIJ,mBAAmB,EAA+B,CAChD,MAAO,MAAK,cAAc,mBACxB,KAAK,WACL,GAIJ,kBAAkB,EAA+B,CAC/C,MAAO,MAAK,cAAc,kBACxB,KAAK,WACL,GAIJ,oBAA0B,CACxB,MAAO,CACL,IAAK,KAAK,WAAW,QACrB,GAAI,KAAK,cAAc,mBAAmB,KAAK,aAInD,0BAA0B,EAAqB,CAC7C,KAAK,WAAW,QAAU,EAAS,IACnC,KAAK,cAAc,0BACjB,KAAK,WACL,EAAS,KA9GR,EAAM,aAmHN,OAAoC,CACzC,UAAU,EAAgC,CACxC,MAAO,GAET,WAAW,EAAuB,EAA2B,CAC3D,MAAO,GAET,YAAY,EAAgC,CAC1C,MAAO,GAET,aAAa,EAAgC,CAC3C,MAAO,GAET,gBAAgB,EAAiC,EACjD,sBAAsB,EAAuB,EAAqB,EAClE,sBAAsB,EAAuB,EAAqB,EAClE,uBAAuB,EAAuB,EAAsB,EACpE,qBAAqB,EAAuB,EAAqB,EACjE,mBAAmB,EAA+B,CAChD,MAAO,GAET,kBAAkB,EAA+B,CAC/C,MAAO,GAET,oBAA0B,CACxB,MAAO,GAET,0BAA0B,EAAqB,GA3B1C,EAAM,gBA5QE,iDAHT",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var gdjs;(function(l){const
|
|
1
|
+
var gdjs;(function(l){const n=new l.Logger("PIXI Image manager"),T=(u,e)=>{n.error("Unable to load file "+u+" with error:",e||"(unknown error)")},d=(u,e)=>{!u||e.smoothed||(u.baseTexture.scaleMode=PIXI.SCALE_MODES.NEAREST)},A=(u,e)=>{e&&!e.smoothed&&(u.magFilter=THREE.NearestFilter,u.minFilter=THREE.NearestFilter)},g=["image","video"];class x{constructor(e){this._loadedTextures=new l.ResourceCache;this._diskTextures=new Map;this._rectangleTextures=new Map;this._scaledTextures=new Map;this._getImageResource=e=>{const r=this._resourceLoader.getResource(e);return r&&this.getResourceKinds().includes(r.kind)?r:null};this._resourceLoader=e,this._invalidTexture=PIXI.Texture.from("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMAAAADACAMAAABlApw1AAAAkFBMVEWdIvr///+hOfrx6v7i0/39/P+eK/rn2v6vbPv7+f/cx/359v/38v7s4v7Wvf3LqvzFnvysY/v18P6jQvrz7P7u5P7ezP3Or/yoV/qlTfrq3v7l1v3hz/2fLvrTuPy0efufMvraxP3YwP3AlPu2fvuuavvRtPy8i/uqXfu5hvvIo/y4gvuxcvugNfq+j/vCmfxfwZ2lAAAF60lEQVR42uzPMQ0AAAjEQPBvmhkBDE+uAppcdXgfAHXY9R4AAAAAAAAAAGAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAEA/YAQAMNfa2nCoMhmE4HxhcFESggMhGtNa11NLl/d9dO53pQRMklPKn4TllhuEdEjb/CK/WWPXvBTjOOVxvDsvVO3u03e8EnC9BZnNMwNcfYDU728NkLpoDLpmPSQU6Ax5vNsfE0lpbwOs1AYGbroDnBCQyPQH7tQsanpYAqwQVftEQEKWgE9AHtAkIpTV1QBOD1Jk4IPJA6y9tQF2C2Io24ApqXq4OMHgBvTsSBjgVBnA9P7HH2xEGPOM+7hVPQdhGUZRvt4/WeHvCgBJ3uFXYsn4m/BO3HJ2Ko8XuMSogQBdvzXoYFRCjQ3GazWQuRIfKms1o0Skge3DmMxvdckiWzoyGu0dIvGhO0+kAkmBW4/UVRPw0qwAfopKpmRPwh0N0ZGrmBPyDyI2Yms6AaiH48nd3g8hmsijMFkrZ9UQSwCFY9j+EHpgor1wM4gaO9oAKog0TtDEGuxoQIF7DOcZwqQEB4kJe4Bt83QHOEiJLuAGe2QG2KuAF37HUHVAn0wZsdAfs/WkD8pkHrGrtSyhWBVgxhnti5m1itsZg/IUiIO4NKJQBzoFjoJjRB6hfZA0T/U8xTEASkMo7TfEtJLGa4CB81JYeZM3PAmQfUQUEtsUY+zx66N6I+MTuySFJPk48Sl9ACYH/1s6dICkKQwEYfg9NkE1QdhkREXGZ1rn/7aZmrR4SAdHnMpXvAF31txETSPA/BXjy9QBiV0KKAhNuCwA5E5vS1hWZtYc+XBScYbDhAVsDm7xeuxYX2GQUzwgAu9+cHrFzkuoCTcAamz7ar6O46QiQr6WNLVGAOFjjjrE88rsDIskHRxRQYVPecTlEszvAEP8tVAErbFrDJ0sHRceuAA8FCVXAB2u/81OjiOW8PUAXR9CJKsCfY4OtwSeFhRJm2haQGpJ5EFUAjLCp6vGQL9gUlwM8yUyaLmDcccXeGyjleKf+f3IOdAHiILc5CD8FMuzLZg8SmiWOIMKAr9gxhvYMLzKCsp5onbe0cUUY4KMgb6y5sN1I183Y+yM2Q3EE+VQB8mXjqIDPEhtvFJE+4Cg7t2Nv8EZn0oAdCnSh8SZWQRrALWxijS+dtqAfQcMDwETBmMM/fB1vcCYOWKGo+cup3VBgnYgDtKDHjXB/gUNl5I9Z8z7bCE9THMgjD0gZCmwfmg4BDhEW5AGwRlHGocmfWni9KdAHTIyeF780MvBKrCIIEMS9HwhtTYZXCeARAVrQfz/wrMRrlBQBohol7C3I8KQOGPZVPSbAH0kLJnBBlS+wm/PleFiSBIg22PoZiLi/yZ3AkC9zRuG69hLhoCplwHKMMtaOQwu+XR3itfnXOvcOq9VMe8aGp5mNUqUPT9crADyUcyZAgCAAdJSzvwIBgoDEQjlWJu/xWoaVgRfMa+0dAuBg4MUE178xYDuR2t8zAI4MLyfE6fAAvhsxKeN81wDIsYUVbQYGrMZ4QcTvGwBrbGWXX0/XBvDDmOEFQQp3DuARdljEiQa9cf+Y4WWb+289LiLsNB+7uz4RxS7WGbbIKfZO85phD8Y8Ko/bWcJBwt/PdlMzMLDduqDZ/L0zsDcrdJxFNI3dX+JppDuOM8c+oiXV7vXVCB8gO9Ftv/czJJdplOcHuGshLfNEfABiFyKlbEl+gqOoGZKJl484gjLLkEa4HTobfYlxxGrtgWcpzzremf7x2OO4vMoMvBsWnjkQB4gmEd5J8PU5r2nj23yEt1scORAFdCsm0znD4Zg9/eC0a+JuVa0bOARb5BXpor4/v8qdOV7DDstvKQd4kYAfllW/l+Sx+RfzW+XDDy8V8BPnyc511wvHCQPb+F3DDDsIHcfJStc9p5w//zRrL1qazH7ZJ6nP4a8XOI77IlTAld4w4FVu7qqA31SAClABKkAFqAAVoAJUgApQASpABagAFaACVIAKUAH/TcB7e/uA7+03ZsJSaNOuAAAAAElFTkSuQmCC",{width:192,height:192}),this._loadedThreeTextures=new Hashtable,this._loadedThreeMaterials=new Hashtable}getResourceKinds(){return g}getPIXITexture(e){const r=this._getImageResource(e);if(!r)return n.warn('Unable to find texture for resource "'+e+'".'),this._invalidTexture;const t=this._loadedTextures.get(r);return t?t.valid?t:(n.error("Texture for "+e+" is not valid anymore (or never was)."),this._invalidTexture):this._invalidTexture}getOrLoadPIXITexture(e){const r=this._getImageResource(e);if(!r)return n.warn('Unable to find texture for resource "'+e+'".'),this._invalidTexture;const t=this._loadedTextures.get(r);if(t)return t.valid?t:(n.error("Texture for "+e+" is not valid anymore (or never was)."),this._invalidTexture);n.log('Loading texture for resource "'+e+'"...');const i=r.file,o=this._resourceLoader.getFullUrl(i),s=PIXI.Texture.from(o,{resourceOptions:{crossorigin:this._resourceLoader.checkIfCredentialsRequired(i)?"use-credentials":"anonymous"}}).on("error",a=>{T(i,a)});if(!s)throw new Error("Texture loading by PIXI returned nothing for file "+i+" behind url "+o);return d(s,r),this._loadedTextures.set(r,s),s}getThreeTexture(e){const r=this._loadedThreeTextures.get(e);if(r)return r;const t=this.getPIXITexture(e);if(!this._resourceLoader._runtimeGame.getRenderer().getPIXIRenderer())throw new Error("No PIXI renderer was found.");const o=t.baseTexture.resource.source;if(!(o instanceof HTMLImageElement))throw new Error(`Can't load texture for resource "${e}" as it's not an image.`);const s=new THREE.Texture(o);s.magFilter=THREE.LinearFilter,s.minFilter=THREE.LinearFilter,s.wrapS=THREE.RepeatWrapping,s.wrapT=THREE.RepeatWrapping,s.colorSpace=THREE.SRGBColorSpace,s.needsUpdate=!0;const a=this._getImageResource(e);return A(s,a),this._loadedThreeTextures.put(e,s),s}getThreeMaterial(e,{useTransparentTexture:r,forceBasicMaterial:t,vertexColors:i}){const o=`${e}|${r?1:0}|${t?1:0}|${i?1:0}`,s=this._loadedThreeMaterials.get(o);if(s)return s;const a=t?new THREE.MeshBasicMaterial({map:this.getThreeTexture(e),side:r?THREE.DoubleSide:THREE.FrontSide,transparent:r,vertexColors:i}):new THREE.MeshStandardMaterial({map:this.getThreeTexture(e),side:r?THREE.DoubleSide:THREE.FrontSide,transparent:r,metalness:0,vertexColors:i});return this._loadedThreeMaterials.put(o,a),a}getPIXIVideoTexture(e){if(e==="")return this._invalidTexture;const r=this._getImageResource(e);if(!r)return n.warn('Unable to find video texture for resource "'+e+'".'),this._invalidTexture;const t=this._loadedTextures.get(r);return t||this._invalidTexture}getInvalidPIXITexture(){return this._invalidTexture}async loadResource(e){const r=this._resourceLoader.getResource(e);if(!r){n.warn('Unable to find texture for resource "'+e+'".');return}await this._loadTexture(r)}async processResource(e){}async _loadTexture(e){if(!this._loadedTextures.get(e))try{if(e.kind==="video")await new Promise((r,t)=>{const i=PIXI.Texture.from(this._resourceLoader.getFullUrl(e.file),{resourceOptions:{crossorigin:this._resourceLoader.checkIfCredentialsRequired(e.file)?"use-credentials":"anonymous",autoPlay:!1}}).on("error",s=>{t(s)});i.baseTexture.on("loaded",()=>{this._loadedTextures.set(e,i),d(i,e),r()}).on("error",s=>{t(s)})});else{const r=PIXI.Texture.from(this._resourceLoader.getFullUrl(e.file),{resourceOptions:{autoLoad:!1,crossorigin:this._resourceLoader.checkIfCredentialsRequired(e.file)?"use-credentials":"anonymous"}});await r.baseTexture.resource.load(),this._loadedTextures.set(e,r),d(r,e)}}catch(r){T(e.file,r)}}getOrCreateDiskTexture(e,r){let t=this._diskTextures.get(e);if(!t){const i=new PIXI.Graphics;i.lineStyle(0,0,0),i.beginFill(l.rgbToHexNumber(255,255,255),1),i.drawCircle(0,0,e),i.endFill(),t=r.generateTexture(i),i.destroy(),this._diskTextures.set(e,t)}return t}getOrCreateRectangleTexture(e,r,t){const i=`${e}_${r}`;let o=this._rectangleTextures.get(i);if(!o){const s=new PIXI.Graphics;s.lineStyle(0,0,0),s.beginFill(l.rgbToHexNumber(255,255,255),1),s.drawRect(0,0,e,r),s.endFill(),o=t.generateTexture(s),s.destroy(),this._rectangleTextures.set(i,o)}return o}getOrCreateScaledTexture(e,r,t,i){const o=`${e}_${r}_${t}`;let s=this._scaledTextures.get(o);if(!s){const a=new PIXI.Graphics,c=new PIXI.Sprite(this.getPIXITexture(e));c.width=r,c.height=t,a.addChild(c),s=i.generateTexture(a),a.destroy(),this._scaledTextures.set(o,s)}return s}dispose(){this._loadedTextures.clear();const e=[];this._loadedThreeTextures.values(e),this._loadedThreeTextures.clear();for(const t of e)t.dispose();const r=[];this._loadedThreeMaterials.values(r),this._loadedThreeMaterials.clear();for(const t of r)t.dispose();for(const t of this._diskTextures.values())t.destroyed||t.destroy();this._diskTextures.clear();for(const t of this._rectangleTextures.values())t.destroyed||t.destroy();this._rectangleTextures.clear();for(const t of this._scaledTextures.values())t.destroyed||t.destroy();this._scaledTextures.clear()}}l.PixiImageManager=x,l.ImageManager=l.PixiImageManager})(gdjs||(gdjs={}));
|
|
2
2
|
//# sourceMappingURL=pixi-image-manager.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../GDevelop/GDJS/Runtime/pixi-renderers/pixi-image-manager.ts"],
|
|
4
|
-
"sourcesContent": ["/*\n * GDevelop JS Platform\n * Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.\n * This project is released under the MIT License.\n */\nnamespace gdjs {\n const logger = new gdjs.Logger('PIXI Image manager');\n\n const logFileLoadingError = (file: string, error: Error | undefined) => {\n logger.error(\n 'Unable to load file ' + file + ' with error:',\n error ? error : '(unknown error)'\n );\n };\n\n const applyTextureSettings = (\n texture: PIXI.Texture | undefined,\n resourceData: ResourceData\n ) => {\n if (!texture) return;\n\n if (!resourceData.smoothed) {\n texture.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST;\n }\n };\n\n const applyThreeTextureSettings = (\n threeTexture: THREE.Texture,\n resourceData: ResourceData | null\n ) => {\n if (resourceData && !resourceData.smoothed) {\n threeTexture.magFilter = THREE.NearestFilter;\n threeTexture.minFilter = THREE.NearestFilter;\n }\n };\n\n const resourceKinds: Array<ResourceKind> = ['image', 'video'];\n\n /**\n * PixiImageManager loads and stores textures that can be used by the Pixi.js renderers.\n */\n export class PixiImageManager implements gdjs.ResourceManager {\n /**\n * The invalid texture is a 8x8 PNG file filled with magenta (#ff00ff), to be\n * easily spotted if rendered on screen.\n */\n private _invalidTexture: PIXI.Texture;\n\n /**\n * Map associating a resource name to the loaded PixiJS texture.\n */\n private _loadedTextures = new gdjs.ResourceCache<PIXI.Texture>();\n\n /**\n * Map associating a resource name to the loaded Three.js texture.\n */\n private _loadedThreeTextures: Hashtable<THREE.Texture>;\n private _loadedThreeMaterials: Hashtable<THREE.Material>;\n\n private _diskTextures = new Map<float, PIXI.Texture>();\n private _rectangleTextures = new Map<string, PIXI.Texture>();\n private _scaledTextures = new Map<string, PIXI.Texture>();\n\n private _resourceLoader: gdjs.ResourceLoader;\n\n /**\n * @param resources The resources data of the game.\n * @param resourceLoader The resources loader of the game.\n */\n constructor(resourceLoader: gdjs.ResourceLoader) {\n this._resourceLoader = resourceLoader;\n this._invalidTexture = PIXI.Texture.from(\n 'data:image/png;base64,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',\n { width: 192, height: 192 }\n );\n this._loadedThreeTextures = new Hashtable();\n this._loadedThreeMaterials = new Hashtable();\n }\n\n getResourceKinds(): ResourceKind[] {\n return resourceKinds;\n }\n\n /**\n * Return the PIXI texture associated to the specified resource name.\n * Returns a placeholder texture if not found.\n * @param resourceName The name of the resource\n * @returns The requested texture, or a placeholder if not found.\n */\n getPIXITexture(resourceName: string): PIXI.Texture {\n const resource = this._getImageResource(resourceName);\n if (!resource) {\n logger.warn(\n 'Unable to find texture for resource \"' + resourceName + '\".'\n );\n return this._invalidTexture;\n }\n\n const existingTexture = this._loadedTextures.get(resource);\n if (!existingTexture) {\n return this._invalidTexture;\n }\n if (!existingTexture.valid) {\n logger.error(\n 'Texture for ' +\n resourceName +\n ' is not valid anymore (or never was).'\n );\n return this._invalidTexture;\n }\n\n return existingTexture;\n }\n\n /**\n * Return the PIXI texture associated to the specified resource name.\n * If not found in the loaded textures, this method will try to load it.\n * Warning: this method should only be used in specific cases that cannot rely on\n * the initial resources loading of the game, such as the splashscreen.\n * @param resourceName The name of the resource\n * @returns The requested texture, or a placeholder if not valid.\n */\n getOrLoadPIXITexture(resourceName: string): PIXI.Texture {\n const resource = this._getImageResource(resourceName);\n if (!resource) {\n logger.warn(\n 'Unable to find texture for resource \"' + resourceName + '\".'\n );\n return this._invalidTexture;\n }\n\n const existingTexture = this._loadedTextures.get(resource);\n if (existingTexture) {\n if (existingTexture.valid) {\n return existingTexture;\n } else {\n logger.error(\n 'Texture for ' +\n resourceName +\n ' is not valid anymore (or never was).'\n );\n return this._invalidTexture;\n }\n }\n\n logger.log('Loading texture for resource \"' + resourceName + '\"...');\n const file = resource.file;\n const url = this._resourceLoader.getFullUrl(file);\n const texture = PIXI.Texture.from(url, {\n resourceOptions: {\n // Note that using `false`\n // to not having `crossorigin` at all would NOT work because the browser would taint the\n // loaded resource so that it can't be read/used in a canvas (it's only working for display `<img>` on screen).\n crossorigin: this._resourceLoader.checkIfCredentialsRequired(file)\n ? 'use-credentials'\n : 'anonymous',\n },\n }).on('error', (error) => {\n logFileLoadingError(file, error);\n });\n if (!texture) {\n throw new Error(\n 'Texture loading by PIXI returned nothing for file ' +\n file +\n ' behind url ' +\n url\n );\n }\n applyTextureSettings(texture, resource);\n\n this._loadedTextures.set(resource, texture);\n return texture;\n }\n\n /**\n * Return the three.js texture associated to the specified resource name.\n * Returns a placeholder texture if not found.\n * @param resourceName The name of the resource\n * @returns The requested texture, or a placeholder if not found.\n */\n getThreeTexture(resourceName: string): THREE.Texture {\n const loadedThreeTexture = this._loadedThreeTextures.get(resourceName);\n if (loadedThreeTexture) {\n return loadedThreeTexture;\n }\n\n // Texture is not loaded, load it now from the PixiJS texture.\n // TODO (3D) - optimization: don't load the PixiJS Texture if not used by PixiJS.\n // TODO (3D) - optimization: Ideally we could even share the same WebGL texture.\n const pixiTexture = this.getPIXITexture(resourceName);\n const pixiRenderer = this._resourceLoader._runtimeGame\n .getRenderer()\n .getPIXIRenderer();\n if (!pixiRenderer) throw new Error('No PIXI renderer was found.');\n\n // @ts-ignore - source does exist on resource.\n const image = pixiTexture.baseTexture.resource.source;\n if (!(image instanceof HTMLImageElement)) {\n throw new Error(\n `Can't load texture for resource \"${resourceName}\" as it's not an image.`\n );\n }\n\n const threeTexture = new THREE.Texture(image);\n threeTexture.magFilter = THREE.LinearFilter;\n threeTexture.minFilter = THREE.LinearFilter;\n threeTexture.wrapS = THREE.RepeatWrapping;\n threeTexture.wrapT = THREE.RepeatWrapping;\n threeTexture.colorSpace = THREE.SRGBColorSpace;\n threeTexture.needsUpdate = true;\n\n const resource = this._getImageResource(resourceName);\n\n applyThreeTextureSettings(threeTexture, resource);\n this._loadedThreeTextures.put(resourceName, threeTexture);\n\n return threeTexture;\n }\n\n /**\n * Return the three.js material associated to the specified resource name.\n * @param resourceName The name of the resource\n * @param options\n * @returns The requested material.\n */\n getThreeMaterial(\n resourceName: string,\n {\n useTransparentTexture,\n forceBasicMaterial,\n }: { useTransparentTexture: boolean; forceBasicMaterial: boolean }\n ): THREE.Material {\n const cacheKey = `${resourceName}|${useTransparentTexture ? 1 : 0}|${\n forceBasicMaterial ? 1 : 0\n }`;\n\n const loadedThreeMaterial = this._loadedThreeMaterials.get(cacheKey);\n if (loadedThreeMaterial) return loadedThreeMaterial;\n\n const material = forceBasicMaterial\n ? new THREE.MeshBasicMaterial({\n map: this.getThreeTexture(resourceName),\n side: useTransparentTexture ? THREE.DoubleSide : THREE.FrontSide,\n transparent: useTransparentTexture,\n })\n : new THREE.MeshStandardMaterial({\n map: this.getThreeTexture(resourceName),\n side: useTransparentTexture ? THREE.DoubleSide : THREE.FrontSide,\n transparent: useTransparentTexture,\n metalness: 0,\n });\n this._loadedThreeMaterials.put(cacheKey, material);\n return material;\n }\n\n /**\n * Return the PIXI video texture associated to the specified resource name.\n * Returns a placeholder texture if not found.\n * @param resourceName The name of the resource to get.\n */\n getPIXIVideoTexture(resourceName: string) {\n if (resourceName === '') {\n return this._invalidTexture;\n }\n const resource = this._getImageResource(resourceName);\n if (!resource) {\n logger.warn(\n 'Unable to find video texture for resource \"' + resourceName + '\".'\n );\n return this._invalidTexture;\n }\n\n const texture = this._loadedTextures.get(resource);\n if (!texture) {\n return this._invalidTexture;\n }\n return texture;\n }\n\n private _getImageResource = (resourceName: string): ResourceData | null => {\n const resource = this._resourceLoader.getResource(resourceName);\n return resource && this.getResourceKinds().includes(resource.kind)\n ? resource\n : null;\n };\n\n /**\n * Return a PIXI texture which can be used as a placeholder when no\n * suitable texture can be found.\n */\n getInvalidPIXITexture() {\n return this._invalidTexture;\n }\n\n /**\n * Load the specified resources, so that textures are loaded and can then be\n * used by calling `getPIXITexture`.\n */\n async loadResource(resourceName: string): Promise<void> {\n const resource = this._resourceLoader.getResource(resourceName);\n if (!resource) {\n logger.warn(\n 'Unable to find texture for resource \"' + resourceName + '\".'\n );\n return;\n }\n await this._loadTexture(resource);\n }\n\n async processResource(resourceName: string): Promise<void> {\n // Do nothing because images are light enough to be parsed in background.\n }\n\n /**\n * Load the specified resources, so that textures are loaded and can then be\n * used by calling `getPIXITexture`.\n * @param onProgress Callback called each time a new file is loaded.\n */\n async _loadTexture(resource: ResourceData): Promise<void> {\n if (this._loadedTextures.get(resource)) {\n return;\n }\n try {\n if (resource.kind === 'video') {\n // For videos, we want to preload them so they are available as soon as we want to use them.\n // We cannot use Pixi.assets.load() as it does not allow passing options (autoplay) to the resource loader.\n // Pixi.Texture.from() does not return a promise, so we need to ensure we look at the 'loaded' event of the baseTexture,\n // to continue, otherwise if we try to play the video too soon (at the beginning of scene for instance),\n // it will fail.\n await new Promise<void>((resolve, reject) => {\n const texture = PIXI.Texture.from(\n this._resourceLoader.getFullUrl(resource.file),\n {\n resourceOptions: {\n crossorigin: this._resourceLoader.checkIfCredentialsRequired(\n resource.file\n )\n ? 'use-credentials'\n : 'anonymous',\n autoPlay: false,\n },\n }\n ).on('error', (error) => {\n reject(error);\n });\n\n const baseTexture = texture.baseTexture;\n baseTexture\n .on('loaded', () => {\n this._loadedTextures.set(resource, texture);\n applyTextureSettings(texture, resource);\n resolve();\n })\n .on('error', (error) => {\n reject(error);\n });\n });\n } else {\n // If the file has no extension, PIXI.assets.load cannot find\n // an adequate load parser and does not load the file although\n // we would like to force it to load (we are confident it's an image).\n // TODO: When PIXI v8+ is used, PIXI.Assets.load can be used because\n // loadParser can be forced in PIXI.Assets.load\n // (see https://github.com/pixijs/pixijs/blob/71ed56c569ebc6b53da19e3c49258a0a84892101/packages/assets/src/loader/Loader.ts#L68)\n const loadedTexture = PIXI.Texture.from(\n this._resourceLoader.getFullUrl(resource.file),\n {\n resourceOptions: {\n autoLoad: false,\n crossorigin: this._resourceLoader.checkIfCredentialsRequired(\n resource.file\n )\n ? 'use-credentials'\n : 'anonymous',\n },\n }\n );\n await loadedTexture.baseTexture.resource.load();\n\n this._loadedTextures.set(resource, loadedTexture);\n // TODO What if 2 assets share the same file with different settings?\n applyTextureSettings(loadedTexture, resource);\n }\n } catch (error) {\n logFileLoadingError(resource.file, error);\n }\n }\n\n /**\n * Return a texture containing a circle filled with white.\n * @param radius The circle radius\n * @param pixiRenderer The renderer used to generate the texture\n */\n getOrCreateDiskTexture(\n radius: float,\n pixiRenderer: PIXI.Renderer\n ): PIXI.Texture {\n let particleTexture = this._diskTextures.get(radius);\n if (!particleTexture) {\n const graphics = new PIXI.Graphics();\n graphics.lineStyle(0, 0, 0);\n graphics.beginFill(gdjs.rgbToHexNumber(255, 255, 255), 1);\n graphics.drawCircle(0, 0, radius);\n graphics.endFill();\n particleTexture = pixiRenderer.generateTexture(graphics);\n graphics.destroy();\n\n this._diskTextures.set(radius, particleTexture);\n }\n return particleTexture;\n }\n\n /**\n * Return a texture filled with white.\n * @param width The texture width\n * @param height The texture height\n * @param pixiRenderer The renderer used to generate the texture\n */\n getOrCreateRectangleTexture(\n width: float,\n height: float,\n pixiRenderer: PIXI.Renderer\n ): PIXI.Texture {\n const key = `${width}_${height}`;\n let particleTexture = this._rectangleTextures.get(key);\n if (!particleTexture) {\n const graphics = new PIXI.Graphics();\n graphics.lineStyle(0, 0, 0);\n graphics.beginFill(gdjs.rgbToHexNumber(255, 255, 255), 1);\n graphics.drawRect(0, 0, width, height);\n graphics.endFill();\n particleTexture = pixiRenderer.generateTexture(graphics);\n graphics.destroy();\n\n this._rectangleTextures.set(key, particleTexture);\n }\n return particleTexture;\n }\n\n /**\n * Return a texture rescaled according to given dimensions.\n * @param width The texture width\n * @param height The texture height\n * @param pixiRenderer The renderer used to generate the texture\n */\n getOrCreateScaledTexture(\n imageResourceName: string,\n width: float,\n height: float,\n pixiRenderer: PIXI.Renderer\n ): PIXI.Texture {\n const key = `${imageResourceName}_${width}_${height}`;\n let particleTexture = this._scaledTextures.get(key);\n if (!particleTexture) {\n const graphics = new PIXI.Graphics();\n const sprite = new PIXI.Sprite(this.getPIXITexture(imageResourceName));\n sprite.width = width;\n sprite.height = height;\n graphics.addChild(sprite);\n particleTexture = pixiRenderer.generateTexture(graphics);\n graphics.destroy();\n\n this._scaledTextures.set(key, particleTexture);\n }\n return particleTexture;\n }\n\n /**\n * To be called when the game is disposed.\n * Clear caches of loaded textures and materials.\n */\n dispose(): void {\n this._loadedTextures.clear();\n\n const threeTextures: THREE.Texture[] = [];\n this._loadedThreeTextures.values(threeTextures);\n this._loadedThreeTextures.clear();\n for (const threeTexture of threeTextures) {\n threeTexture.dispose();\n }\n\n const threeMaterials: THREE.Material[] = [];\n this._loadedThreeMaterials.values(threeMaterials);\n this._loadedThreeMaterials.clear();\n for (const threeMaterial of threeMaterials) {\n threeMaterial.dispose();\n }\n\n for (const pixiTexture of this._diskTextures.values()) {\n if (pixiTexture.destroyed) {\n continue;\n }\n\n pixiTexture.destroy();\n }\n this._diskTextures.clear();\n\n for (const pixiTexture of this._rectangleTextures.values()) {\n if (pixiTexture.destroyed) {\n continue;\n }\n\n pixiTexture.destroy();\n }\n this._rectangleTextures.clear();\n\n for (const pixiTexture of this._scaledTextures.values()) {\n if (pixiTexture.destroyed) {\n continue;\n }\n\n pixiTexture.destroy();\n }\n this._scaledTextures.clear();\n }\n }\n\n //Register the class to let the engine use it.\n export const ImageManager = gdjs.PixiImageManager;\n export type ImageManager = gdjs.PixiImageManager;\n}\n"],
|
|
5
|
-
"mappings": "AAKA,GAAU,MAAV,UAAU,EAAV,CACE,KAAM,GAAS,GAAI,GAAK,OAAO,sBAEzB,EAAsB,CAAC,EAAc,IAA6B,CACtE,EAAO,MACL,uBAAyB,EAAO,eAChC,GAAgB,oBAId,EAAuB,CAC3B,EACA,IACG,CACH,AAAI,CAAC,GAEA,EAAa,UAChB,GAAQ,YAAY,UAAY,KAAK,YAAY,UAI/C,EAA4B,CAChC,EACA,IACG,CACH,AAAI,GAAgB,CAAC,EAAa,UAChC,GAAa,UAAY,MAAM,cAC/B,EAAa,UAAY,MAAM,gBAI7B,EAAqC,CAAC,QAAS,SAK9C,OAAuD,
|
|
4
|
+
"sourcesContent": ["/*\n * GDevelop JS Platform\n * Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.\n * This project is released under the MIT License.\n */\nnamespace gdjs {\n const logger = new gdjs.Logger('PIXI Image manager');\n\n const logFileLoadingError = (file: string, error: Error | undefined) => {\n logger.error(\n 'Unable to load file ' + file + ' with error:',\n error ? error : '(unknown error)'\n );\n };\n\n const applyTextureSettings = (\n texture: PIXI.Texture | undefined,\n resourceData: ResourceData\n ) => {\n if (!texture) return;\n\n if (!resourceData.smoothed) {\n texture.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST;\n }\n };\n\n const applyThreeTextureSettings = (\n threeTexture: THREE.Texture,\n resourceData: ResourceData | null\n ) => {\n if (resourceData && !resourceData.smoothed) {\n threeTexture.magFilter = THREE.NearestFilter;\n threeTexture.minFilter = THREE.NearestFilter;\n }\n };\n\n const resourceKinds: Array<ResourceKind> = ['image', 'video'];\n\n /**\n * PixiImageManager loads and stores textures that can be used by the Pixi.js renderers.\n */\n export class PixiImageManager implements gdjs.ResourceManager {\n /**\n * The invalid texture is a 8x8 PNG file filled with magenta (#ff00ff), to be\n * easily spotted if rendered on screen.\n */\n private _invalidTexture: PIXI.Texture;\n\n /**\n * Map associating a resource name to the loaded PixiJS texture.\n */\n private _loadedTextures = new gdjs.ResourceCache<PIXI.Texture>();\n\n /**\n * Map associating a resource name to the loaded Three.js texture.\n */\n private _loadedThreeTextures: Hashtable<THREE.Texture>;\n private _loadedThreeMaterials: Hashtable<THREE.Material>;\n\n private _diskTextures = new Map<float, PIXI.Texture>();\n private _rectangleTextures = new Map<string, PIXI.Texture>();\n private _scaledTextures = new Map<string, PIXI.Texture>();\n\n private _resourceLoader: gdjs.ResourceLoader;\n\n /**\n * @param resourceLoader The resources loader of the game.\n */\n constructor(resourceLoader: gdjs.ResourceLoader) {\n this._resourceLoader = resourceLoader;\n this._invalidTexture = PIXI.Texture.from(\n 'data:image/png;base64,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',\n { width: 192, height: 192 }\n );\n this._loadedThreeTextures = new Hashtable();\n this._loadedThreeMaterials = new Hashtable();\n }\n\n getResourceKinds(): ResourceKind[] {\n return resourceKinds;\n }\n\n /**\n * Return the PIXI texture associated to the specified resource name.\n * Returns a placeholder texture if not found.\n * @param resourceName The name of the resource\n * @returns The requested texture, or a placeholder if not found.\n */\n getPIXITexture(resourceName: string): PIXI.Texture {\n const resource = this._getImageResource(resourceName);\n if (!resource) {\n logger.warn(\n 'Unable to find texture for resource \"' + resourceName + '\".'\n );\n return this._invalidTexture;\n }\n\n const existingTexture = this._loadedTextures.get(resource);\n if (!existingTexture) {\n return this._invalidTexture;\n }\n if (!existingTexture.valid) {\n logger.error(\n 'Texture for ' +\n resourceName +\n ' is not valid anymore (or never was).'\n );\n return this._invalidTexture;\n }\n\n return existingTexture;\n }\n\n /**\n * Return the PIXI texture associated to the specified resource name.\n * If not found in the loaded textures, this method will try to load it.\n * Warning: this method should only be used in specific cases that cannot rely on\n * the initial resources loading of the game, such as the splashscreen.\n * @param resourceName The name of the resource\n * @returns The requested texture, or a placeholder if not valid.\n */\n getOrLoadPIXITexture(resourceName: string): PIXI.Texture {\n const resource = this._getImageResource(resourceName);\n if (!resource) {\n logger.warn(\n 'Unable to find texture for resource \"' + resourceName + '\".'\n );\n return this._invalidTexture;\n }\n\n const existingTexture = this._loadedTextures.get(resource);\n if (existingTexture) {\n if (existingTexture.valid) {\n return existingTexture;\n } else {\n logger.error(\n 'Texture for ' +\n resourceName +\n ' is not valid anymore (or never was).'\n );\n return this._invalidTexture;\n }\n }\n\n logger.log('Loading texture for resource \"' + resourceName + '\"...');\n const file = resource.file;\n const url = this._resourceLoader.getFullUrl(file);\n const texture = PIXI.Texture.from(url, {\n resourceOptions: {\n // Note that using `false`\n // to not having `crossorigin` at all would NOT work because the browser would taint the\n // loaded resource so that it can't be read/used in a canvas (it's only working for display `<img>` on screen).\n crossorigin: this._resourceLoader.checkIfCredentialsRequired(file)\n ? 'use-credentials'\n : 'anonymous',\n },\n }).on('error', (error) => {\n logFileLoadingError(file, error);\n });\n if (!texture) {\n throw new Error(\n 'Texture loading by PIXI returned nothing for file ' +\n file +\n ' behind url ' +\n url\n );\n }\n applyTextureSettings(texture, resource);\n\n this._loadedTextures.set(resource, texture);\n return texture;\n }\n\n /**\n * Return the three.js texture associated to the specified resource name.\n * Returns a placeholder texture if not found.\n * @param resourceName The name of the resource\n * @returns The requested texture, or a placeholder if not found.\n */\n getThreeTexture(resourceName: string): THREE.Texture {\n const loadedThreeTexture = this._loadedThreeTextures.get(resourceName);\n if (loadedThreeTexture) {\n return loadedThreeTexture;\n }\n\n // Texture is not loaded, load it now from the PixiJS texture.\n // TODO (3D) - optimization: don't load the PixiJS Texture if not used by PixiJS.\n // TODO (3D) - optimization: Ideally we could even share the same WebGL texture.\n const pixiTexture = this.getPIXITexture(resourceName);\n const pixiRenderer = this._resourceLoader._runtimeGame\n .getRenderer()\n .getPIXIRenderer();\n if (!pixiRenderer) throw new Error('No PIXI renderer was found.');\n\n // @ts-ignore - source does exist on resource.\n const image = pixiTexture.baseTexture.resource.source;\n if (!(image instanceof HTMLImageElement)) {\n throw new Error(\n `Can't load texture for resource \"${resourceName}\" as it's not an image.`\n );\n }\n\n const threeTexture = new THREE.Texture(image);\n threeTexture.magFilter = THREE.LinearFilter;\n threeTexture.minFilter = THREE.LinearFilter;\n threeTexture.wrapS = THREE.RepeatWrapping;\n threeTexture.wrapT = THREE.RepeatWrapping;\n threeTexture.colorSpace = THREE.SRGBColorSpace;\n threeTexture.needsUpdate = true;\n\n const resource = this._getImageResource(resourceName);\n\n applyThreeTextureSettings(threeTexture, resource);\n this._loadedThreeTextures.put(resourceName, threeTexture);\n\n return threeTexture;\n }\n\n /**\n * Return the three.js material associated to the specified resource name.\n * @param resourceName The name of the resource\n * @param options\n * @returns The requested material.\n */\n getThreeMaterial(\n resourceName: string,\n {\n useTransparentTexture,\n forceBasicMaterial,\n vertexColors,\n }: {\n useTransparentTexture: boolean;\n forceBasicMaterial: boolean;\n vertexColors: boolean;\n }\n ): THREE.Material {\n const cacheKey = `${resourceName}|${useTransparentTexture ? 1 : 0}|${\n forceBasicMaterial ? 1 : 0\n }|${vertexColors ? 1 : 0}`;\n\n const loadedThreeMaterial = this._loadedThreeMaterials.get(cacheKey);\n if (loadedThreeMaterial) return loadedThreeMaterial;\n\n const material = forceBasicMaterial\n ? new THREE.MeshBasicMaterial({\n map: this.getThreeTexture(resourceName),\n side: useTransparentTexture ? THREE.DoubleSide : THREE.FrontSide,\n transparent: useTransparentTexture,\n vertexColors,\n })\n : new THREE.MeshStandardMaterial({\n map: this.getThreeTexture(resourceName),\n side: useTransparentTexture ? THREE.DoubleSide : THREE.FrontSide,\n transparent: useTransparentTexture,\n metalness: 0,\n vertexColors,\n });\n this._loadedThreeMaterials.put(cacheKey, material);\n return material;\n }\n\n /**\n * Return the PIXI video texture associated to the specified resource name.\n * Returns a placeholder texture if not found.\n * @param resourceName The name of the resource to get.\n */\n getPIXIVideoTexture(resourceName: string) {\n if (resourceName === '') {\n return this._invalidTexture;\n }\n const resource = this._getImageResource(resourceName);\n if (!resource) {\n logger.warn(\n 'Unable to find video texture for resource \"' + resourceName + '\".'\n );\n return this._invalidTexture;\n }\n\n const texture = this._loadedTextures.get(resource);\n if (!texture) {\n return this._invalidTexture;\n }\n return texture;\n }\n\n private _getImageResource = (resourceName: string): ResourceData | null => {\n const resource = this._resourceLoader.getResource(resourceName);\n return resource && this.getResourceKinds().includes(resource.kind)\n ? resource\n : null;\n };\n\n /**\n * Return a PIXI texture which can be used as a placeholder when no\n * suitable texture can be found.\n */\n getInvalidPIXITexture() {\n return this._invalidTexture;\n }\n\n /**\n * Load the specified resources, so that textures are loaded and can then be\n * used by calling `getPIXITexture`.\n */\n async loadResource(resourceName: string): Promise<void> {\n const resource = this._resourceLoader.getResource(resourceName);\n if (!resource) {\n logger.warn(\n 'Unable to find texture for resource \"' + resourceName + '\".'\n );\n return;\n }\n await this._loadTexture(resource);\n }\n\n async processResource(resourceName: string): Promise<void> {\n // Do nothing because images are light enough to be parsed in background.\n }\n\n /**\n * Load the specified resources, so that textures are loaded and can then be\n * used by calling `getPIXITexture`.\n * @param onProgress Callback called each time a new file is loaded.\n */\n async _loadTexture(resource: ResourceData): Promise<void> {\n if (this._loadedTextures.get(resource)) {\n return;\n }\n try {\n if (resource.kind === 'video') {\n // For videos, we want to preload them so they are available as soon as we want to use them.\n // We cannot use Pixi.assets.load() as it does not allow passing options (autoplay) to the resource loader.\n // Pixi.Texture.from() does not return a promise, so we need to ensure we look at the 'loaded' event of the baseTexture,\n // to continue, otherwise if we try to play the video too soon (at the beginning of scene for instance),\n // it will fail.\n await new Promise<void>((resolve, reject) => {\n const texture = PIXI.Texture.from(\n this._resourceLoader.getFullUrl(resource.file),\n {\n resourceOptions: {\n crossorigin: this._resourceLoader.checkIfCredentialsRequired(\n resource.file\n )\n ? 'use-credentials'\n : 'anonymous',\n autoPlay: false,\n },\n }\n ).on('error', (error) => {\n reject(error);\n });\n\n const baseTexture = texture.baseTexture;\n baseTexture\n .on('loaded', () => {\n this._loadedTextures.set(resource, texture);\n applyTextureSettings(texture, resource);\n resolve();\n })\n .on('error', (error) => {\n reject(error);\n });\n });\n } else {\n // If the file has no extension, PIXI.assets.load cannot find\n // an adequate load parser and does not load the file although\n // we would like to force it to load (we are confident it's an image).\n // TODO: When PIXI v8+ is used, PIXI.Assets.load can be used because\n // loadParser can be forced in PIXI.Assets.load\n // (see https://github.com/pixijs/pixijs/blob/71ed56c569ebc6b53da19e3c49258a0a84892101/packages/assets/src/loader/Loader.ts#L68)\n const loadedTexture = PIXI.Texture.from(\n this._resourceLoader.getFullUrl(resource.file),\n {\n resourceOptions: {\n autoLoad: false,\n crossorigin: this._resourceLoader.checkIfCredentialsRequired(\n resource.file\n )\n ? 'use-credentials'\n : 'anonymous',\n },\n }\n );\n await loadedTexture.baseTexture.resource.load();\n\n this._loadedTextures.set(resource, loadedTexture);\n // TODO What if 2 assets share the same file with different settings?\n applyTextureSettings(loadedTexture, resource);\n }\n } catch (error) {\n logFileLoadingError(resource.file, error);\n }\n }\n\n /**\n * Return a texture containing a circle filled with white.\n * @param radius The circle radius\n * @param pixiRenderer The renderer used to generate the texture\n */\n getOrCreateDiskTexture(\n radius: float,\n pixiRenderer: PIXI.Renderer\n ): PIXI.Texture {\n let particleTexture = this._diskTextures.get(radius);\n if (!particleTexture) {\n const graphics = new PIXI.Graphics();\n graphics.lineStyle(0, 0, 0);\n graphics.beginFill(gdjs.rgbToHexNumber(255, 255, 255), 1);\n graphics.drawCircle(0, 0, radius);\n graphics.endFill();\n particleTexture = pixiRenderer.generateTexture(graphics);\n graphics.destroy();\n\n this._diskTextures.set(radius, particleTexture);\n }\n return particleTexture;\n }\n\n /**\n * Return a texture filled with white.\n * @param width The texture width\n * @param height The texture height\n * @param pixiRenderer The renderer used to generate the texture\n */\n getOrCreateRectangleTexture(\n width: float,\n height: float,\n pixiRenderer: PIXI.Renderer\n ): PIXI.Texture {\n const key = `${width}_${height}`;\n let particleTexture = this._rectangleTextures.get(key);\n if (!particleTexture) {\n const graphics = new PIXI.Graphics();\n graphics.lineStyle(0, 0, 0);\n graphics.beginFill(gdjs.rgbToHexNumber(255, 255, 255), 1);\n graphics.drawRect(0, 0, width, height);\n graphics.endFill();\n particleTexture = pixiRenderer.generateTexture(graphics);\n graphics.destroy();\n\n this._rectangleTextures.set(key, particleTexture);\n }\n return particleTexture;\n }\n\n /**\n * Return a texture rescaled according to given dimensions.\n * @param width The texture width\n * @param height The texture height\n * @param pixiRenderer The renderer used to generate the texture\n */\n getOrCreateScaledTexture(\n imageResourceName: string,\n width: float,\n height: float,\n pixiRenderer: PIXI.Renderer\n ): PIXI.Texture {\n const key = `${imageResourceName}_${width}_${height}`;\n let particleTexture = this._scaledTextures.get(key);\n if (!particleTexture) {\n const graphics = new PIXI.Graphics();\n const sprite = new PIXI.Sprite(this.getPIXITexture(imageResourceName));\n sprite.width = width;\n sprite.height = height;\n graphics.addChild(sprite);\n particleTexture = pixiRenderer.generateTexture(graphics);\n graphics.destroy();\n\n this._scaledTextures.set(key, particleTexture);\n }\n return particleTexture;\n }\n\n /**\n * To be called when the game is disposed.\n * Clear caches of loaded textures and materials.\n */\n dispose(): void {\n this._loadedTextures.clear();\n\n const threeTextures: THREE.Texture[] = [];\n this._loadedThreeTextures.values(threeTextures);\n this._loadedThreeTextures.clear();\n for (const threeTexture of threeTextures) {\n threeTexture.dispose();\n }\n\n const threeMaterials: THREE.Material[] = [];\n this._loadedThreeMaterials.values(threeMaterials);\n this._loadedThreeMaterials.clear();\n for (const threeMaterial of threeMaterials) {\n threeMaterial.dispose();\n }\n\n for (const pixiTexture of this._diskTextures.values()) {\n if (pixiTexture.destroyed) {\n continue;\n }\n\n pixiTexture.destroy();\n }\n this._diskTextures.clear();\n\n for (const pixiTexture of this._rectangleTextures.values()) {\n if (pixiTexture.destroyed) {\n continue;\n }\n\n pixiTexture.destroy();\n }\n this._rectangleTextures.clear();\n\n for (const pixiTexture of this._scaledTextures.values()) {\n if (pixiTexture.destroyed) {\n continue;\n }\n\n pixiTexture.destroy();\n }\n this._scaledTextures.clear();\n }\n }\n\n //Register the class to let the engine use it.\n export const ImageManager = gdjs.PixiImageManager;\n export type ImageManager = gdjs.PixiImageManager;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|